From f6be92767d1d002f5e90a4673ee4e6d4f1e1744f Mon Sep 17 00:00:00 2001 From: Chris Liddell Date: Wed, 16 Dec 2020 06:03:10 +0100 Subject: [PATCH] [truetype] Fix incremental metrics (#59503). * src/truetype/ttgload.c (tt_get_metrics, load_truetype_glyph): Previously, the code would populate the phantom points before calling the `get_glyph_metrics` callback. For formats like PCL XL format 1, class 2 downloaded fonts (where metrics are removed from the TTF header), this causes problems when the hinting program uses the phantom points (misplaced and distorted glyphs) due to the metrics being unset (all zeros). (tt_get_metrics_incr_overrides): Renamed to... (tt_get_metrics_incremental): ... this. Updated caller * include/freetype/ftincrem.h: Update the documentation to make it clearer that `get_glyph_metrics` is to retrieve metrics from a non-standard source, but *not* for the purpose of imposing custom metrics. --- ChangeLog | 19 +++++++++++++++++++ include/freetype/ftincrem.h | 15 ++++++++++----- src/truetype/ttgload.c | 33 ++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a5796e92..3c935647d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2020-12-16 Chris Liddell + + [truetype] Fix incremental metrics (#59503). + + * src/truetype/ttgload.c (tt_get_metrics, load_truetype_glyph): + Previously, the code would populate the phantom points before + calling the `get_glyph_metrics` callback. For formats like PCL XL + format 1, class 2 downloaded fonts (where metrics are removed from + the TTF header), this causes problems when the hinting program uses + the phantom points (misplaced and distorted glyphs) due to the + metrics being unset (all zeros). + (tt_get_metrics_incr_overrides): Renamed to... + (tt_get_metrics_incremental): ... this. Updated caller + + * include/freetype/ftincrem.h: Update the documentation to make it + clearer that `get_glyph_metrics` is to retrieve metrics from a + non-standard source, but *not* for the purpose of imposing custom + metrics. + 2020-12-14 Werner Lemberg [type42] Pacify static analysis tools (#59682). diff --git a/include/freetype/ftincrem.h b/include/freetype/ftincrem.h index f67655eda..54145c1d1 100644 --- a/include/freetype/ftincrem.h +++ b/include/freetype/ftincrem.h @@ -213,9 +213,14 @@ FT_BEGIN_HEADER * * @description: * A function used to retrieve the basic metrics of a given glyph index - * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place - * from the glyph images proper. + * before accessing its data. This allows for handling font types such + * as PCL~XL Format~1, Class~2 downloaded TrueType fonts, where the glyph + * metrics (`hmtx` and `vmtx` tables) are permitted to be omitted from + * the font, and the relevant metrics included in the header of the glyph + * outline data. Importantly, this is not intended to allow custom glyph + * metrics (for example, Postscript Metrics dictionaries), because that + * conflicts with the requirements of outline hinting. Such custom + * metrics must be handled separately, by the calling application. * * @input: * incremental :: @@ -235,7 +240,7 @@ FT_BEGIN_HEADER * * @output: * ametrics :: - * The replacement glyph metrics in font units. + * The glyph metrics in font units. * */ typedef FT_Error @@ -264,7 +269,7 @@ FT_BEGIN_HEADER * * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does not - * provide overriding glyph metrics. + * require it. * */ typedef struct FT_Incremental_FuncsRec_ diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index d08a97565..81cecbb85 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -197,10 +197,17 @@ } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( !loader->linear_def ) +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* With the incremental interface, these values are set by */ + /* a call to `tt_get_metrics_incremental'. */ + if ( face->root.internal->incremental_interface == NULL ) +#endif { - loader->linear_def = 1; - loader->linear = advance_width; + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } } return FT_Err_Ok; @@ -210,8 +217,8 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL static void - tt_get_metrics_incr_overrides( TT_Loader loader, - FT_UInt glyph_index ) + tt_get_metrics_incremental( TT_Loader loader, + FT_UInt glyph_index ) { TT_Face face = loader->face; @@ -1741,13 +1748,11 @@ if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + tt_get_metrics_incremental( loader, glyph_index ); +#endif tt_loader_set_pp( loader ); -#ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); -#endif #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1830,13 +1835,11 @@ goto Exit; } - /* must initialize phantom points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + tt_get_metrics_incremental( loader, glyph_index ); +#endif tt_loader_set_pp( loader ); -#ifdef FT_CONFIG_OPTION_INCREMENTAL - tt_get_metrics_incr_overrides( loader, glyph_index ); -#endif /***********************************************************************/ /***********************************************************************/