From cc576f8002666c914f3c340844a01d739e9942ee Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Tue, 20 Dec 2016 11:37:42 +0100 Subject: [PATCH] [truetype] Fix linear metrics of GX variation fonts. When asking for an unhinted non-default variations, `linearVertAdvance' is currently the value from the `hmtx' table instead of the actual value after applying the variation. `HVAR' support fixes this, but fonts will exist without that table and will need sane fallback. * src/truetype/ttgload.c (TT_Process_Simple_Glyph, load_truetype_glyph): Implement linear advance adjustments if `HVAR' or `VVAR' tables are missing. --- ChangeLog | 15 ++++++++++++++ src/truetype/ttgload.c | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/ChangeLog b/ChangeLog index 11c9d80ce..f34831707 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2016-12-20 Ben Wagner + Werner Lemberg + + [truetype] Fix linear metrics of GX variation fonts. + + When asking for an unhinted non-default variations, + `linearVertAdvance' is currently the value from the `hmtx' table + instead of the actual value after applying the variation. `HVAR' + support fixes this, but fonts will exist without that table and will + need sane fallback. + + * src/truetype/ttgload.c (TT_Process_Simple_Glyph, + load_truetype_glyph): Implement linear advance adjustments if `HVAR' + or `VVAR' tables are missing. + 2016-12-20 Werner Lemberg [cff, truetype] Fast advance width retrieval for fonts with HVAR. diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 6ada4027e..06e862110 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -888,11 +888,25 @@ if ( loader->face->doblend && !loader->face->is_default_instance ) { + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)loader->face->var; + + /* Deltas apply to the unscaled data. */ error = TT_Vary_Apply_Glyph_Deltas( loader->face, loader->glyph_index, outline, (FT_UInt)n_points ); + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( var && var->hadvance_adjust ) ) + loader->linear = outline->points[n_points - 3].x - + outline->points[n_points - 4].x; + if ( !( var && var->vadvance_adjust ) ) + loader->vadvance = outline->points[n_points - 1].x - + outline->points[n_points - 2].x; + if ( error ) return error; } @@ -1566,6 +1580,10 @@ if ( loader->face->doblend && !loader->face->is_default_instance ) { + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)loader->face->var; + + /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ FT_Vector points[4]; @@ -1607,6 +1625,14 @@ loader->pp3.y = points[2].y; loader->pp4.x = points[3].x; loader->pp4.y = points[3].y; + + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( var && var->hadvance_adjust ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( var && var->vadvance_adjust ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1729,6 +1755,10 @@ if ( face->doblend && !face->is_default_instance ) { + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)face->var; + + short i, limit; FT_SubGlyph subglyph; @@ -1824,6 +1854,13 @@ loader->pp4.x = points[i + 3].x; loader->pp4.y = points[i + 3].y; + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( var && var->hadvance_adjust ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( var && var->vadvance_adjust ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; + Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); @@ -1883,6 +1920,9 @@ { FT_Vector pp[4]; + FT_Int linear_hadvance; + FT_Int linear_vadvance; + /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ @@ -1895,6 +1935,9 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; + linear_hadvance = loader->linear; + linear_vadvance = loader->vadvance; + num_base_points = (FT_UInt)gloader->base.outline.n_points; error = load_truetype_glyph( loader, @@ -1914,6 +1957,9 @@ loader->pp2 = pp[1]; loader->pp3 = pp[2]; loader->pp4 = pp[3]; + + loader->linear = linear_hadvance; + loader->vadvance = linear_vadvance; } num_points = (FT_UInt)gloader->base.outline.n_points;