[gs-cvs] rev 7582 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Mon Jan 8 04:50:48 PST 2007


Author: leonardo
Date: 2007-01-08 04:50:48 -0800 (Mon, 08 Jan 2007)
New Revision: 7582

Modified:
   trunk/gs/src/gstype1.c
   trunk/gs/src/gstype2.c
   trunk/gs/src/gxhintn.c
   trunk/gs/src/gxhintn.h
Log:
Type 1 hinter : Implementing a contour sign normalization, part 1.

DETAILS :

This is a preparation for fixing the bug 688947  
"Ghostscript renders font incorrectly (letter 'o' filled in)".

Several fonts in wild appear to violate the Type 1
restriction for inner contours to be of negative sign.
They cause a wrong rendering of some glyphs,
such as 'o' in the test case. Rather we consider
those fonts to be incorrect, we need a workaround for them
because this annoying problem appears too frequently.
At last CET 16-01.PS defines such font.

We assume that True Types always have right contours,
because (1) we didn't meet such cases in practice.
We also assume that resident fonts always have right contours,
bvecause resident fonts usually don't come from wild.

Therefore we need 4 working modes for type 1 hinter :
1. "pass_through" : no hinting, no contour adjustment.
   Works for resident fonts of a big size,
   and/or when the target is the path bbox accumulator.
2. "disable_hinting" : no hinting, contour ajdustment is on.
   Works for non-resident Type 1 fonts of a big size,
3. The hinting is enabled, the contour adjustment is disabled.
   Works for not-big non-resident fonts except True Types.
   We want to save CPU time expense from the contour adjustment.
4. The hinting is enabled, the contour adjustment is enabled.
   Works for not-big embedded Type 1 fonts.

This change is algorithmically equivalent.
It define necesary flags and data flows,
which will be used in the implementation.
The implementation itself will be a next step.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gstype1.c
===================================================================
--- trunk/gs/src/gstype1.c	2007-01-08 05:50:33 UTC (rev 7581)
+++ trunk/gs/src/gstype1.c	2007-01-08 12:50:48 UTC (rev 7582)
@@ -93,7 +93,8 @@
 			    gs_currentaligntopixels(pfont->dir));
 	    if (code < 0)
 	    	return code;
-	    code = t1_hinter__set_font_data(h, 1, pdata, pcis->no_grid_fitting);
+	    code = t1_hinter__set_font_data(h, 1, pdata, pcis->no_grid_fitting, 
+			    pcis->pfont->is_resource);
 	    if (code < 0)
 	    	return code;
 	    break;

Modified: trunk/gs/src/gstype2.c
===================================================================
--- trunk/gs/src/gstype2.c	2007-01-08 05:50:33 UTC (rev 7581)
+++ trunk/gs/src/gstype2.c	2007-01-08 12:50:48 UTC (rev 7582)
@@ -157,7 +157,8 @@
 			    gs_currentaligntopixels(pfont->dir));
 	    if (code < 0)
 	    	return code;
-	    code = t1_hinter__set_font_data(h, 2, pdata, pcis->no_grid_fitting);
+	    code = t1_hinter__set_font_data(h, 2, pdata, pcis->no_grid_fitting,
+			    pcis->pfont->is_resource);
 	    if (code < 0)
 	    	return code;
 	    break;

Modified: trunk/gs/src/gxhintn.c
===================================================================
--- trunk/gs/src/gxhintn.c	2007-01-08 05:50:33 UTC (rev 7581)
+++ trunk/gs/src/gxhintn.c	2007-01-08 12:50:48 UTC (rev 7582)
@@ -513,7 +513,9 @@
     this->output_path = output_path;
     this->memory = (output_path == 0 ? 0 : output_path->memory);
     this->disable_hinting = (this->memory == NULL);
+    this->pass_through = this->disable_hinting;
     this->autohinting = false;
+    this->fix_contour_sign = false;
 
     this->stem_snap[0][0] = this->stem_snap[1][0] = 100; /* default */
 }
@@ -625,6 +627,7 @@
     int code;
 
     this->disable_hinting |= (scale < 1/1024. || scale > 4);
+    this->pass_through |= this->disable_hinting;
     this->log2_pixels_x = log2_pixels_x;
     this->log2_pixels_y = log2_pixels_y;
     this->log2_subpixels_x = log2_subpixels_x;
@@ -649,6 +652,7 @@
     if (this->ctmf.denominator == 0 || this->ctmi.denominator == 0) {
 	/* ctmf should be degenerate. */
     	this->disable_hinting = true;
+	this->pass_through = true;
 	this->ctmf.denominator = 1;
     }
     this->transposed = (any_abs(this->ctmf.xy) * 10 > any_abs(this->ctmf.xx));
@@ -705,7 +709,7 @@
 	 * The ADOBE_OVERSHOOT_COMPATIBILIY build needs to fix them.
 	 */
     }
-    if (1 || /* Doesn't work - see comment above. Using this->disable_hinting instead. */
+    if (1 || /* Doesn't work - see comment above. */
 	    this->resolution * this->font_size >= 2) {	
 	/* Enable the grid fitting separately for axes : */
 	this->grid_fit_y = (any_abs(this->ctmf.xy) * 10 < any_abs(this->ctmf.xx) ||
@@ -851,7 +855,7 @@
     vd_setlinewidth(0);
 }
 
-int t1_hinter__set_font_data(t1_hinter * this, int FontType, gs_type1_data *pdata, bool no_grid_fitting)
+int t1_hinter__set_font_data(t1_hinter * this, int FontType, gs_type1_data *pdata, bool no_grid_fitting, bool is_resource)
 {   int code;
 
     t1_hinter__init_outline(this);
@@ -863,10 +867,14 @@
     this->overshoot_threshold = (this->heigt_transform_coef != 0 ? (t1_glyph_space_coord)(fixed_half * (1 << this->log2_pixels_y) / this->heigt_transform_coef) : 0);
     this->ForceBold = pdata->ForceBold;
     this->disable_hinting |= no_grid_fitting;
+    this->pass_through |= no_grid_fitting;
     this->charpath_flag = no_grid_fitting;
-    if (!vd_enabled && (VD_DRAW_IMPORT || this->disable_hinting))
+    this->fix_contour_sign = (!is_resource && this->memory != NULL);
+    if (this->fix_contour_sign)
+	this->pass_through = false;
+    if (!vd_enabled && (VD_DRAW_IMPORT || this->pass_through))
 	enable_draw_import();
-    if (this->disable_hinting)
+    if (this->pass_through)
 	return 0;
     code = t1_hinter__set_alignment_zones(this, pdata->OtherBlues.values, pdata->OtherBlues.count, botzone, false);
     if (code >= 0)
@@ -900,12 +908,12 @@
     this->suppress_overshoots = (this->BlueScale > this->heigt_transform_coef / (1 << this->log2_pixels_y) - 0.00020417);
     this->overshoot_threshold = (this->heigt_transform_coef != 0 ? (t1_glyph_space_coord)(fixed_half * (1 << this->log2_pixels_y) / this->heigt_transform_coef) : 0);
     this->ForceBold = false;
-    this->disable_hinting |= no_grid_fitting;
+    this->pass_through |= no_grid_fitting;
     this->charpath_flag = no_grid_fitting;
     this->autohinting = true;
-    if (!vd_enabled && (VD_DRAW_IMPORT || this->disable_hinting))
+    if (!vd_enabled && (VD_DRAW_IMPORT || this->pass_through))
 	enable_draw_import();
-    if (this->disable_hinting)
+    if (this->pass_through)
 	return 0;
     /* Currently we don't provice alignments zones or stem snap. */
     return 0;
@@ -1043,7 +1051,7 @@
 		}
 	    }
 	}
-	/* Leave the loop here because t1_hinter_fix_missed_flex
+	/* Leave the loop here because t1_hinter__fix_missed_flex
 	   will try the interval starting with the next pole. 
 	   We reserve the 'i' cycle for fonding a "best" flex
 	   within the interval. */
@@ -1116,7 +1124,7 @@
 	}
 }
 
-private void t1_hinter_fix_missed_flex(t1_hinter * this)
+private void t1_hinter__fix_missed_flex(t1_hinter * this)
 {
     int contour_beg, contour_end;
     int i, j, k, pj, n, j0, j1;
@@ -1200,7 +1208,7 @@
 
     t1_hinter__adjust_matrix_precision(this, xx, yy);
     if (this->flex_count == 0) {
-	if (this->disable_hinting) {
+	if (this->pass_through) {
 	    t1_glyph_space_coord gx = this->cx += xx;
 	    t1_glyph_space_coord gy = this->cy += yy;
 	    fixed fx, fy;
@@ -1229,7 +1237,7 @@
 		return code;
 	}
 	if (!this->have_flex)
-	    t1_hinter_fix_missed_flex(this);
+	    t1_hinter__fix_missed_flex(this);
     }
     code = t1_hinter__add_pole(this, xx, yy, moveto);
     if (this->flex_count == 0) {
@@ -1256,7 +1264,7 @@
 int t1_hinter__rlineto(t1_hinter * this, fixed xx, fixed yy)
 {   
     t1_hinter__adjust_matrix_precision(this, xx, yy);
-    if (this->disable_hinting) {
+    if (this->pass_through) {
 	t1_glyph_space_coord gx = this->cx += xx;
 	t1_glyph_space_coord gy = this->cy += yy;
 	fixed fx, fy;
@@ -1281,7 +1289,7 @@
     t1_hinter__adjust_matrix_precision(this, xx0, yy0);
     t1_hinter__adjust_matrix_precision(this, xx1, yy1);
     t1_hinter__adjust_matrix_precision(this, xx2, yy2);
-    if (this->disable_hinting) {
+    if (this->pass_through) {
 	t1_glyph_space_coord gx0 = this->cx += xx0;
 	t1_glyph_space_coord gy0 = this->cy += yy0;
 	t1_glyph_space_coord gx1 = this->cx += xx1;
@@ -1340,7 +1348,7 @@
 }
 
 int t1_hinter__closepath(t1_hinter * this)
-{   if (this->disable_hinting) {
+{   if (this->pass_through) {
 	vd_lineto(this->bx, this->by);
 	this->path_opened = false;
         return gx_path_close_subpath(this->output_path);
@@ -1349,7 +1357,7 @@
 
 	if (contour_beg == this->pole_count)
 	    return 0; /* maybe a single trailing moveto */
-	if (vd_enabled && (VD_DRAW_IMPORT || this->disable_hinting)) {
+	if (vd_enabled && (VD_DRAW_IMPORT || this->pass_through)) {
 	    vd_setcolor(VD_IMPORT_COLOR);
 	    vd_setlinewidth(0);
 	    vd_lineto(this->bx, this->by);
@@ -1392,7 +1400,7 @@
 	return_error(gs_error_invalidfont);
     this->flex_count++;
     this->have_flex = true;
-    if (this->disable_hinting)
+    if (this->pass_through)
 	return t1_hinter__rmoveto(this, 0, 0);
     return 0;
 }
@@ -1423,7 +1431,7 @@
 	vd_moveto (pole0[0].gx, pole0[0].gy);
 	vd_curveto(pole0[2].gx, pole0[2].gy, pole0[3].gx, pole0[3].gy, pole0[4].gx, pole0[4].gy);
 	vd_curveto(pole0[5].gx, pole0[5].gy, pole0[6].gx, pole0[6].gy, pole0[7].gx, pole0[7].gy);
-	if (this->disable_hinting) {
+	if (this->pass_through) {
 	    fixed fx0, fy0, fx1, fy1, fx2, fy2;
 	    int code;
 
@@ -1451,7 +1459,7 @@
 	/* do with line */
 	vd_moveto(pole0[0].gx, pole0[0].gy);
 	vd_lineto(pole0[7].gx, pole0[7].gy);
-	if (this->disable_hinting) {
+	if (this->pass_through) {
 	    fixed fx, fy;
 
 	    g2d(this, pole0[7].gx, pole0[7].gy, &fx, &fy);
@@ -2949,6 +2957,11 @@
     return t1_hinter__rmoveto(this, gx - this->cx, gy - this->cy);
 }
 
+private void t1_hinter__fix_contour_signs(t1_hinter * this)
+{
+    /* fixme: todo. */
+}
+
 int t1_hinter__endglyph(t1_hinter * this)
 {   int code = 0;
 
@@ -2997,8 +3010,11 @@
 	    Current implementation paints exported rotated glyph in wrong coordinates.
 	*/
     }
-    if (this->pole_count)
+    if (this->pole_count) {
+	if (this->fix_contour_sign)
+	    t1_hinter__fix_contour_signs(this);
 	code = t1_hinter__export(this);
+    }
 exit:
     t1_hinter__free_arrays(this);
     vd_release_dc;

Modified: trunk/gs/src/gxhintn.h
===================================================================
--- trunk/gs/src/gxhintn.h	2007-01-08 05:50:33 UTC (rev 7581)
+++ trunk/gs/src/gxhintn.h	2007-01-08 12:50:48 UTC (rev 7582)
@@ -129,10 +129,12 @@
     bool transposed;
     bool align_to_pixels; /* false == "align to (integral) pixels" */
     bool disable_hinting;
+    bool pass_through;
     bool grid_fit_x, grid_fit_y;
     bool charpath_flag;
     bool path_opened;
     bool autohinting;
+    bool fix_contour_sign;
     t1_glyph_space_coord blue_shift, blue_fuzz;
     t1_pole pole0[T1_MAX_POLES], *pole;
     t1_hint hint0[T1_MAX_HINTS], *hint;
@@ -154,7 +156,7 @@
     int hint_applying_count, max_hint_applying_count;
     int primary_hint_count;
     int flex_count;
-    int FontType; /* 1 or 2 */
+    int FontType; /* 1 or 2 or 42 */
     bool have_flex;
     bool ForceBold;
     bool keep_stem_width;
@@ -184,7 +186,7 @@
 			int log2_subpixels_x, int log2_subpixels_y,
 			fixed origin_x, fixed origin_y, bool align_to_pixels);
 int  t1_hinter__set_font_data(t1_hinter * this, int FontType, gs_type1_data *pdata, 
-			bool no_grid_fitting);
+			bool no_grid_fitting, bool is_resource);
 int  t1_hinter__set_font42_data(t1_hinter * this, int FontType, gs_type42_data *pdata, 
 			bool no_grid_fitting);
 



More information about the gs-cvs mailing list