Commit cc576f8002666c914f3c340844a01d739e9942ee

Ben Wagner 2016-12-20T11:37:42

[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.

diff --git a/ChangeLog b/ChangeLog
index 11c9d80..f348317 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2016-12-20  Ben Wagner  <bungeman@google.com>
+	    Werner Lemberg  <wl@gnu.org>
+
+	[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  <wl@gnu.org>
 
 	[cff, truetype] Fast advance width retrieval for fonts with HVAR.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 6ada402..06e8621 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;