Commit 6c831d658f879e542be0b789fbc38e4f45a33ace

Alexei Podtelezhnikov 2021-12-11T22:34:27

[truetype] Initialize the loader with `hdmx` data. The `hdmx` matching can be done before the glyph is loaded. * include/freetype/internal/tttypes.h (TT_LoaderRec): Add a field. * src/truetype/ttgload.c (compute_glyph_metrics): Relocate the `hdmx` code from here... (tt_loader_init): ... to here, before the glyph is loaded.

diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 651131c..fcd97cf 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1769,6 +1769,9 @@ FT_BEGIN_HEADER
     /* since version 2.6.2 */
     FT_ListRec       composites;
 
+    /* since version 2.11.2 */
+    FT_Byte*         widthp;
+
   } TT_LoaderRec;
 
 
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 4419852..f18c6c2 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2230,10 +2230,6 @@
                          FT_UInt    glyph_index )
   {
     TT_Face    face   = loader->face;
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-#endif
 
     FT_BBox       bbox;
     FT_Fixed      y_scale;
@@ -2256,37 +2252,10 @@
 
     glyph->metrics.horiBearingX = bbox.xMin;
     glyph->metrics.horiBearingY = bbox.yMax;
-    glyph->metrics.horiAdvance  = SUB_LONG(loader->pp2.x, loader->pp1.x);
-
-    /* Adjust advance width to the value contained in the hdmx table   */
-    /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
-    /* mode of the v40 interpreter is active.  See `ttinterp.h' for    */
-    /* details on backward compatibility mode.                         */
-    if ( IS_HINTED( loader->load_flags )                                &&
-         !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )              &&
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-         !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
-            ( loader->exec && loader->exec->backward_compatibility  ) ) &&
-#endif
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-         !( driver->interpreter_version == TT_INTERPRETER_VERSION_38  &&
-            !SPH_OPTION_BITMAP_WIDTHS                                 &&
-            FT_LOAD_TARGET_MODE( loader->load_flags ) !=
-                                                 FT_RENDER_MODE_MONO  &&
-            ( loader->exec && !loader->exec->compatible_widths )      ) &&
-#endif
-         !face->postscript.isFixedPitch                                 )
-    {
-      FT_Byte*  widthp;
-
-
-      widthp = tt_face_get_device_metrics( face,
-                                           size->metrics->x_ppem,
-                                           glyph_index );
-
-      if ( widthp )
-        glyph->metrics.horiAdvance = *widthp * 64;
-    }
+    if ( loader->widthp )
+      glyph->metrics.horiAdvance = loader->widthp[glyph_index] * 64;
+    else
+      glyph->metrics.horiAdvance = SUB_LONG(loader->pp2.x, loader->pp1.x);
 
     /* set glyph dimensions */
     glyph->metrics.width  = SUB_LONG( bbox.xMax, bbox.xMin );
@@ -2752,6 +2721,32 @@
       exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
       loader->exec = exec;
       loader->instructions = exec->glyphIns;
+
+      /* Use the hdmx table if any unless FT_LOAD_COMPUTE_METRICS */
+      /* is set or backward compatibility mode of the v38 or v40  */
+      /* interpreters is active.  See `ttinterp.h' for details on */
+      /* backward compatibility mode.                             */
+      if ( IS_HINTED( loader->load_flags )                                &&
+           !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )              &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+           !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
+              exec->backward_compatibility                              ) &&
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+           !( driver->interpreter_version == TT_INTERPRETER_VERSION_38  &&
+              !SPH_OPTION_BITMAP_WIDTHS                                 &&
+              FT_LOAD_TARGET_MODE( loader->load_flags ) !=
+                                                   FT_RENDER_MODE_MONO  &&
+              exec->compatible_widths                                   ) &&
+#endif
+           !face->postscript.isFixedPitch                                 )
+      {
+        loader->widthp = tt_face_get_device_metrics( face,
+                                                     size->metrics->x_ppem,
+                                                     0 );
+      }
+      else
+        loader->widthp = NULL;
     }
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */