An improved patch for 687156 and 687175

"Igor V. Melichev" <[email protected]>
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
The patch
http://www.ghostscript.com/pipermail/gs-code-review/2003-December/004269.html
is not longer necessary.
This one fixes that problem in a more general way.

[Log message beg]
Fix (type 1 hinter) : sbw was wrongly accounted with FontBBox over 4095
units.

DETAILS :

Side bearing and width was accounted before import_shift is adjusted to
FontBBox.
Bug 687156 "some characters shifted higher in acrobat4 generated eps".

Besides that, it prevents a fixed overflow when FontBBox is zero and glyph
coordinates are big.
Bug 687175 "(type 1 hinter) A fixed overflow can happen".

This patch removes import_shift.
Instead that it dynamically reduces the number of fraction bits
in transformation matrices during the glyph import.

Minor change : removed some obsolete comments.

EXPECTED DIFFERENCES :

None.

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
patch.txt (text/plain, 16.5 KB)
Changes: 
 
 
 
*** f:\casper\HEAD\gs\src\gxhintn.c	Mon Nov 10 19:55:00 2003
--- files\gs\src\gxhintn.c	Tue Dec  2 13:03:38 2003
***************
*** 41,47 ****
      - Adobe looks adjusting the relative stem length.
      - Test Adobe compatibility for rotated/skewed glyphs.
-     - Fix glyph placement along X-coordinate.
-     - Test this code with fixed_shift != 12.
-     - Remove rudiments of old code from gstype1.c, gstype2.c .
   */
  
--- 41,44 ----
***************
*** 182,189 ****
  }
  
- private inline int32 import_shift(int32 v, unsigned int s)
- {   return v >> s;
- }
- 
  private inline int32 Max(int32 a, int32 b)
  {   return a > b ? a : b;
--- 179,182 ----
***************
*** 194,201 ****
  }
  
- private inline double Maxd(double a, double b)
- {   return a > b ? a : b;
- }
- 
  private inline long rshift(long a, int b)
  {   return b > 0 ? a << b : a >> -b;
--- 187,190 ----
***************
*** 213,223 ****
  }
  
- private inline void double_matrix__scale(double_matrix * this, double sx, double sy)
- {   this->xx *= sx;
-     this->xy *= sy;
-     this->yx *= sx;
-     this->yy *= sy;
- }
- 
  private inline int double_matrix__invert_to(const double_matrix * this, double_matrix * m)
  {   double det = this->xx * this->yy - this->xy * this->yx;
--- 202,205 ----
***************
*** 246,250 ****
      double scale = max(axx + axy, ayx + ayy);
      int matrix_exp, m;
!     double unused = frexp(scale,&matrix_exp);
  
      this->bitshift = matrix_bits - matrix_exp;
--- 228,232 ----
      double scale = max(axx + axy, ayx + ayy);
      int matrix_exp, m;
!     double unused = frexp(scale, &matrix_exp);
  
      this->bitshift = matrix_bits - matrix_exp;
***************
*** 255,259 ****
      this->yy = (int32)(pmat->yy * this->denominator + 0.5);
      m = Max(Max(any_abs(this->xx), any_abs(this->xy)), Max(any_abs(this->yx), any_abs(this->yy)));
!     unused = frexp(m,&matrix_exp);
      if (matrix_exp > matrix_bits)
          fraction_matrix__drop_bits(this, matrix_exp - matrix_bits);
--- 237,241 ----
      this->yy = (int32)(pmat->yy * this->denominator + 0.5);
      m = Max(Max(any_abs(this->xx), any_abs(this->xy)), Max(any_abs(this->yx), any_abs(this->yy)));
!     unused = frexp(m, &matrix_exp);
      if (matrix_exp > matrix_bits)
          fraction_matrix__drop_bits(this, matrix_exp - matrix_bits);
***************
*** 275,279 ****
      if (code < 0)
  	return code;
!     fraction_matrix__set(pmat,&m);
      return 0;
  }
--- 257,261 ----
      if (code < 0)
  	return code;
!     fraction_matrix__set(pmat, &m);
      return 0;
  }
***************
*** 459,463 ****
  
  void t1_hinter__init(t1_hinter * this, gx_path *output_path)
! {   this->stem_snap_count[0] = this->stem_snap_count[1] = 0;
      this->zone_count = 0;
      this->pole_count = 0;
--- 441,446 ----
  
  void t1_hinter__init(t1_hinter * this, gx_path *output_path)
! {   this->max_import_coord = (1 << max_coord_bits);
!     this->stem_snap_count[0] = this->stem_snap_count[1] = 0;
      this->zone_count = 0;
      this->pole_count = 0;
***************
*** 496,500 ****
      this->charpath_flag = false;
      this->grid_fit_x = this->grid_fit_y = true;
-     this->import_shift = 0;
      this->output_path = output_path;
      this->memory = (output_path == 0 ? 0 : output_path->memory);
--- 479,482 ----
***************
*** 538,541 ****
--- 520,537 ----
  }
  
+ private inline void t1_hinter__adjust_matrix_precision(t1_hinter * this, fixed xx, fixed yy)
+ {   fixed x = any_abs(xx), y = any_abs(yy);
+     fixed c = (x > y ? x : y);
+ 
+     while (c >= this->max_import_coord) {
+ 	/* Reduce the precision of ctmf to allow products to fit into 32 bits : */
+ 	this->max_import_coord <<= 1;
+ 	fraction_matrix__drop_bits(&this->ctmf, 1);
+ 	fraction_matrix__drop_bits(&this->ctmi, 1);
+ 	this->g2o_fraction_bits -= 1;
+ 	this->g2o_fraction >>= 1;
+     }
+ }
+ 
  private inline void t1_hinter__set_origin(t1_hinter * this, fixed dx, fixed dy)
  {   
***************
*** 545,548 ****
--- 541,545 ----
      this->orig_dx = (dx + align_x / 2) & ~(align_x - 1);
      this->orig_dy = (dy + align_y / 2) & ~(align_y - 1);
+     t1_hinter__adjust_matrix_precision(this, this->orig_dx, this->orig_dy);
      this->orig_ox = d2o(this, this->orig_dx);
      this->orig_oy = d2o(this, this->orig_dy);
***************
*** 573,585 ****
      float ayx = fabs(ctm->xx), ayy = fabs(ctm->xy);
      float scale = max(axx + axy, ayx + ayy);
-     double size = Maxd(Maxd(fabs(FontBBox->p.x), fabs(FontBBox->p.y)), 
-                        Maxd(fabs(FontBBox->q.x), fabs(FontBBox->q.y)));
      double_matrix CTM;
      int code;
  
-     while (size >= (1 << split_bits))
- 	++this->import_shift, size = shift_rounded((int)ceil(size), 1);
-     if (size == 0)
- 	size = 1024 * fixed_scale; /* Hack for fonts with no bbox. */
      if (scale == 0)
  	return_error(gs_error_invalidfont);
--- 570,576 ----
***************
*** 590,594 ****
      this->log2_subpixels_y = log2_subpixels_y;
      double_matrix__set(&CTM, ctm);
-     double_matrix__scale(&CTM, 1<<this->import_shift, 1<<this->import_shift);
      fraction_matrix__set(&this->ctmf, &CTM);
      this->g2o_fraction_bits = this->ctmf.bitshift - g2o_bitshift + _fixed_shift;
--- 581,584 ----
***************
*** 601,610 ****
  	return code;
      this->g2o_fraction = 1 << this->g2o_fraction_bits;
!     if (!this->disable_hinting) {
          if (this->g2o_fraction == 0)
      	    return_error(gs_error_limitcheck);
          if (this->ctmf.denominator == 0 || this->ctmi.denominator == 0)
      	    return_error(gs_error_limitcheck); /* Must not pass here. */
-     }
      {   /* height_transform_coef is scaling factor for the
             distance between horizontal lines while transformation.
--- 591,601 ----
  	return code;
      this->g2o_fraction = 1 << this->g2o_fraction_bits;
!     t1_hinter__adjust_matrix_precision(this, float2fixed(FontBBox->p.x), float2fixed(FontBBox->p.y));
!     t1_hinter__adjust_matrix_precision(this, float2fixed(FontBBox->q.x), float2fixed(FontBBox->q.y));
!     /* Note : If FontBBox iz zero, we'll adjust dynamically while importing the glyph. */
      if (this->g2o_fraction == 0)
      	return_error(gs_error_limitcheck);
      if (this->ctmf.denominator == 0 || this->ctmi.denominator == 0)
      	return_error(gs_error_limitcheck); /* Must not pass here. */
      {   /* height_transform_coef is scaling factor for the
             distance between horizontal lines while transformation.
***************
*** 641,645 ****
          this->base_font_scale = d0;
          this->font_size =  floor(d1 / d0 * 10000 + 0.5) / 10000;
!         this->resolution = floor(d2 / (1 << this->import_shift) / d1 * 10000000 + 0.5) / 10000000;
  	/*
  	 * fixme: base_font_scale, font_size and resolution are computed wrongly 
--- 632,636 ----
          this->base_font_scale = d0;
          this->font_size =  floor(d1 / d0 * 10000 + 0.5) / 10000;
!         this->resolution = floor(d2 / d1 * 10000000 + 0.5) / 10000000;
  	/*
  	 * fixme: base_font_scale, font_size and resolution are computed wrongly 
***************
*** 687,692 ****
  
      zone->type = type;
!     zone->y           = import_shift(float2fixed(blues[0] + d), this->import_shift);
!     zone->overshoot_y = import_shift(float2fixed(blues[1] + d), this->import_shift);
      zone->y_min = min(zone->y, zone->overshoot_y) - blue_fuzz;
      zone->y_max = max(zone->y, zone->overshoot_y) + blue_fuzz;
--- 678,683 ----
  
      zone->type = type;
!     zone->y           = float2fixed(blues[0] + d);
!     zone->overshoot_y = float2fixed(blues[1] + d);
      zone->y_min = min(zone->y, zone->overshoot_y) - blue_fuzz;
      zone->y_max = max(zone->y, zone->overshoot_y) + blue_fuzz;
***************
*** 694,697 ****
--- 685,689 ----
          int v = zone->overshoot_y; zone->overshoot_y = zone->y; zone->y = v;
      }
+     t1_hinter__adjust_matrix_precision(this, zone->y_min, zone->y_max);
  }
  
***************
*** 748,752 ****
      	    return_error(gs_error_VMerror);
      for (i = 0; i < count; i++)
!         this->stem_snap[hv][count0 + i] = import_shift(float2fixed(value[i]), this->import_shift);
      this->stem_snap_count[hv] += count;
      return 0;
--- 740,744 ----
      	    return_error(gs_error_VMerror);
      for (i = 0; i < count; i++)
!         this->stem_snap[hv][count0 + i] = float2fixed(value[i]);
      this->stem_snap_count[hv] += count;
      return 0;
***************
*** 760,765 ****
      this->BlueScale = pdata->BlueScale;
      this->blue_shift = float2fixed(pdata->BlueShift);
!     this->blue_fuzz  = import_shift(float2fixed(pdata->BlueFuzz), this->import_shift);
!     this->suppress_overshoots = (this->BlueScale > this->heigt_transform_coef / (1 << this->log2_pixels_y) / (1 << this->import_shift) - 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 = pdata->ForceBold;
--- 752,757 ----
      this->BlueScale = pdata->BlueScale;
      this->blue_shift = float2fixed(pdata->BlueShift);
!     this->blue_fuzz  = float2fixed(pdata->BlueFuzz);
!     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 = pdata->ForceBold;
***************
*** 805,810 ****
      if (code < 0)
  	return code;
!     pole->gx = pole->ax = this->cx += import_shift(xx, this->import_shift);
!     pole->gy = pole->ay = this->cy += import_shift(yy, this->import_shift);
      pole->ox = pole->oy = 0;
      pole->type = type;
--- 797,802 ----
      if (code < 0)
  	return code;
!     pole->gx = pole->ax = this->cx += xx;
!     pole->gy = pole->ay = this->cy += yy;
      pole->ox = pole->oy = 0;
      pole->type = type;
***************
*** 816,829 ****
  
  int t1_hinter__sbw(t1_hinter * this, fixed sbx, fixed sby, fixed wx,  fixed wy)
! {   this->cx = this->orig_gx = this->subglyph_orig_gx = import_shift(sbx, this->import_shift);
!     this->cy = this->orig_gy = this->subglyph_orig_gy = import_shift(sby, this->import_shift);
!     this->width_gx = import_shift(wx, this->import_shift);
!     this->width_gy = import_shift(wy, this->import_shift);
      return 0;
  }
  
  int t1_hinter__sbw_seac(t1_hinter * this, fixed sbx, fixed sby)
! {   this->cx = this->subglyph_orig_gx = this->orig_gx + import_shift(sbx, this->import_shift);
!     this->cy = this->subglyph_orig_gy = this->orig_gy + import_shift(sby, this->import_shift);
      return 0;
  }
--- 808,824 ----
  
  int t1_hinter__sbw(t1_hinter * this, fixed sbx, fixed sby, fixed wx,  fixed wy)
! {   t1_hinter__adjust_matrix_precision(this, sbx, sby);
!     t1_hinter__adjust_matrix_precision(this, wx, wy);
!     this->cx = this->orig_gx = this->subglyph_orig_gx = sbx;
!     this->cy = this->orig_gy = this->subglyph_orig_gy = sby;
!     this->width_gx = wx;
!     this->width_gy = wy;
      return 0;
  }
  
  int t1_hinter__sbw_seac(t1_hinter * this, fixed sbx, fixed sby)
! {   t1_hinter__adjust_matrix_precision(this, sbx, sby);
!     this->cx = this->subglyph_orig_gx = this->orig_gx + sbx;
!     this->cy = this->subglyph_orig_gy = this->orig_gy + sby;
      return 0;
  }
***************
*** 832,839 ****
  {   int code;
  
      if (this->flex_count == 0) {
  	if (this->disable_hinting) {
! 	    t1_glyph_space_coord gx = this->cx += import_shift(xx, this->import_shift);
! 	    t1_glyph_space_coord gy = this->cy += import_shift(yy, this->import_shift);
  	    fixed fx, fy;
  
--- 827,835 ----
  {   int code;
  
+     t1_hinter__adjust_matrix_precision(this, xx, yy);
      if (this->flex_count == 0) {
  	if (this->disable_hinting) {
! 	    t1_glyph_space_coord gx = this->cx += xx;
! 	    t1_glyph_space_coord gy = this->cy += yy;
  	    fixed fx, fy;
  
***************
*** 882,888 ****
  int t1_hinter__rlineto(t1_hinter * this, fixed xx, fixed yy)
  {   
      if (this->disable_hinting) {
! 	t1_glyph_space_coord gx = this->cx += import_shift(xx, this->import_shift);
! 	t1_glyph_space_coord gy = this->cy += import_shift(yy, this->import_shift);
  	fixed fx, fy;
  
--- 878,885 ----
  int t1_hinter__rlineto(t1_hinter * this, fixed xx, fixed yy)
  {   
+     t1_hinter__adjust_matrix_precision(this, xx, yy);
      if (this->disable_hinting) {
! 	t1_glyph_space_coord gx = this->cx += xx;
! 	t1_glyph_space_coord gy = this->cy += yy;
  	fixed fx, fy;
  
***************
*** 904,914 ****
  int t1_hinter__rcurveto(t1_hinter * this, fixed xx0, fixed yy0, fixed xx1, fixed yy1, fixed xx2, fixed yy2)
  {   
      if (this->disable_hinting) {
! 	t1_glyph_space_coord gx0 = this->cx += import_shift(xx0, this->import_shift);
! 	t1_glyph_space_coord gy0 = this->cy += import_shift(yy0, this->import_shift);
! 	t1_glyph_space_coord gx1 = this->cx += import_shift(xx1, this->import_shift);
! 	t1_glyph_space_coord gy1 = this->cy += import_shift(yy1, this->import_shift);
! 	t1_glyph_space_coord gx2 = this->cx += import_shift(xx2, this->import_shift);
! 	t1_glyph_space_coord gy2 = this->cy += import_shift(yy2, this->import_shift);
  	fixed fx0, fy0, fx1, fy1, fx2, fy2;
  
--- 901,914 ----
  int t1_hinter__rcurveto(t1_hinter * this, fixed xx0, fixed yy0, fixed xx1, fixed yy1, fixed xx2, fixed yy2)
  {   
+     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) {
! 	t1_glyph_space_coord gx0 = this->cx += xx0;
! 	t1_glyph_space_coord gy0 = this->cy += yy0;
! 	t1_glyph_space_coord gx1 = this->cx += xx1;
! 	t1_glyph_space_coord gy1 = this->cy += yy1;
! 	t1_glyph_space_coord gx2 = this->cx += xx2;
! 	t1_glyph_space_coord gy2 = this->cy += yy2;
  	fixed fx0, fy0, fx1, fy1, fx2, fy2;
  
***************
*** 940,953 ****
  void t1_hinter__setcurrentpoint(t1_hinter * this, fixed xx, fixed yy)
  {   
!     t1_glyph_space_coord gx = import_shift(xx, this->import_shift);
!     t1_glyph_space_coord gy = import_shift(yy, this->import_shift);
! 
      if (this->FontType != 2) {
  	/* We use this function to set a subglyph origin
  	   for composite glyphs in Type 2 fonts.
  	 */
! 	this->cx = gx;
! 	this->cy = gy;
!     } else if (this->cx != gx || this->cy != gy) {
  	/* Type 1 spec reads : "The setcurrentpoint command is used only 
  	   in conjunction with results from OtherSubrs procedures."
--- 940,951 ----
  void t1_hinter__setcurrentpoint(t1_hinter * this, fixed xx, fixed yy)
  {   
!     t1_hinter__adjust_matrix_precision(this, xx, yy);
      if (this->FontType != 2) {
  	/* We use this function to set a subglyph origin
  	   for composite glyphs in Type 2 fonts.
  	 */
! 	this->cx = xx;
! 	this->cy = yy;
!     } else if (this->cx != xx || this->cy != yy) {
  	/* Type 1 spec reads : "The setcurrentpoint command is used only 
  	   in conjunction with results from OtherSubrs procedures."
***************
*** 958,963 ****
  	   with OtherSubrs. (The check above is debug purpose only.)
  	 */
! 	this->cx = gx;
! 	this->cy = gy;
      }
  }
--- 956,961 ----
  	   with OtherSubrs. (The check above is debug purpose only.)
  	 */
! 	this->cx = xx;
! 	this->cy = yy;
      }
  }
***************
*** 1152,1160 ****
  {   t1_hint *hint;
      t1_glyph_space_coord s = (type == hstem ? this->subglyph_orig_gy : this->subglyph_orig_gx);
!     t1_glyph_space_coord g0 = s + import_shift(v0, this->import_shift);
!     t1_glyph_space_coord g1 = s + import_shift(v0 + v1, this->import_shift);
      t1_hint_range *range;
      int i, code;
  
      for (i = 0; i < this->hint_count; i++)
  	if (this->hint[i].type == type && 
--- 1150,1159 ----
  {   t1_hint *hint;
      t1_glyph_space_coord s = (type == hstem ? this->subglyph_orig_gy : this->subglyph_orig_gx);
!     t1_glyph_space_coord g0 = s + v0;
!     t1_glyph_space_coord g1 = s + v0 + v1;
      t1_hint_range *range;
      int i, code;
  
+     t1_hinter__adjust_matrix_precision(this, g0, g1);
      for (i = 0; i < this->hint_count; i++)
  	if (this->hint[i].type == type && 
 
 
 
*** f:\casper\HEAD\gs\src\gxhintn.h	Tue Oct 21 05:43:28 2003
--- files\gs\src\gxhintn.h	Tue Dec  2 12:49:33 2003
***************
*** 103,107 ****
      fraction_matrix ctmi;
      unsigned int g2o_fraction_bits;
!     unsigned int import_shift;
      int32 g2o_fraction;
      t1_glyph_space_coord orig_gx, orig_gy; /* glyph origin in glyph space */
--- 103,107 ----
      fraction_matrix ctmi;
      unsigned int g2o_fraction_bits;
!     unsigned int max_import_coord;
      int32 g2o_fraction;
      t1_glyph_space_coord orig_gx, orig_gy; /* glyph origin in glyph space */

lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.