diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2020-12-01 18:06:42 +0000 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2020-12-03 16:03:37 +0000 |
commit | fb1a336ac4d2613a63dc0b6054f20f9a8a467fe9 (patch) | |
tree | 2d6984d979c068293774cd941462c3d1a5ca8450 /base/fapi_ft.c | |
parent | fce9bcfbda7acdf758fe6fb5264bb1e78eb39039 (diff) | |
download | ghostpdl-fb1a336ac4d2613a63dc0b6054f20f9a8a467fe9.tar.gz |
Bug 694692: Handle custom left-sidebearing values.
Ghostscript was ending up ignoring LSB values read from Metrics dictionaries.
This stemmed from some confusion about Freetype's incremental interface
API get_metrics call. We had taken the references to "overriding" the metrics
to mean it allowed for custom metrics to be passed into (and back out of)
Freetype. That is not the case: it is intended to allow integrations supporting
"incomplete" (primarily TrueType) fonts, such as PCL/XL embedded TTFs, that are
permitted to omit certain tables - specifically, in this case, the hmtx and vmtx
tables.
So, this drops that approach, and applies custom LSB values in our code.
Coincidentally, this also makes gs somewhat immune from a pending change in
Freetype related to that get_metrics call.
Diffstat (limited to 'base/fapi_ft.c')
-rw-r--r-- | base/fapi_ft.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/base/fapi_ft.c b/base/fapi_ft.c index 21aef2f06..747a44cf2 100644 --- a/base/fapi_ft.c +++ b/base/fapi_ft.c @@ -621,23 +621,34 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, face->ft_inc_int->object->fapi_font = a_fapi_font; /* Store the overriding metrics if they have been supplied. */ - if (face->ft_inc_int - && a_char_ref->metrics_type != gs_fapi_metrics_notdef) { + if (face->ft_inc_int && a_char_ref->metrics_type != gs_fapi_metrics_notdef) { + + FT_Incremental_MetricsRec *m = &face->ft_inc_int->object->glyph_metrics; - FT_Incremental_MetricsRec *m = - &face->ft_inc_int->object->glyph_metrics; m->bearing_x = a_char_ref->sb_x >> 16; m->bearing_y = a_char_ref->sb_y >> 16; m->advance = a_char_ref->aw_x >> 16; + face->ft_inc_int->object->glyph_metrics_index = index; - face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; - /* we only want this for fonts with TT outlines */ - if (!a_fapi_font->is_type1) { - delta.y = 0; - delta.x = FT_MulFix(a_char_ref->sb_x, ft_face->size->metrics.x_scale); - FT_Vector_Transform( &delta, &face->ft_transform); - } + /* For most font types, the original metrics come directly from the font, and + what we have here are customized (such as a Matrics dict in Postscript). We + only want to use the width, in that case, because other metrics can mess up + the hinting in Freetype. We'll apply custom lsb outselves, using the "delta" + stuff below. + The exception here is PCL/XL embedded TTF fonts, where the h/vmtx tables can + be missing, and we *have* to use the explicit metrics from the PCL/XL glyph + data. (NOTE: if those do not match the original font's metrics, again, the hinting + can be distorted) + */ + if (a_char_ref->metrics_type == gs_fapi_metrics_replace && !a_fapi_font->is_mtx_skipped) + face->ft_inc_int->object->metrics_type = gs_fapi_metrics_replace_width; + else + face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; + + delta.x = FT_MulFix(a_char_ref->sb_x >> 16, ft_face->size->metrics.x_scale); + delta.y = FT_MulFix(a_char_ref->sb_y >> 16, ft_face->size->metrics.y_scale); + FT_Vector_Transform( &delta, &face->ft_transform); } else if (face->ft_inc_int) /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */ @@ -719,7 +730,7 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, } if ((!ft_error || !ft_error_fb) && (delta.x != 0 || delta.y != 0)) { - FT_Outline_Translate( &ft_face->glyph->outline, delta.x >> 16, delta.y >> 16 ); + FT_Outline_Translate( &ft_face->glyph->outline, delta.x, delta.y); } /* Previously we interpreted the glyph unscaled, and derived the metrics from that. Now we only interpret it @@ -735,10 +746,10 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, */ hx = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingX * ft_face->units_per_EM * 72.0) / - ((double)face->width * face->horz_res)); + ((double)face->width * face->horz_res)) + (a_fapi_font->is_mtx_skipped == 1 ? 0 : a_char_ref->sb_x >> 16); hy = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingY * ft_face->units_per_EM * 72.0) / - ((double)face->height * face->vert_res)); + ((double)face->height * face->vert_res)) + (a_fapi_font->is_mtx_skipped == 1 ? 0 : a_char_ref->sb_y >> 16); w = (FT_Long) (((double)ft_face->glyph->metrics.width * ft_face->units_per_EM * 72.0) / ((double)face->width * |