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 */