Commit 2067c6985ac896523afd0dc7327f317d766fc82d

Werner Lemberg 2016-09-29T19:49:07

[truetype] Disallow bitmap strokes for non-default instances. Also speed up access of default instances if GX variations are active. * include/freetype/internal/tttypes.h (TT_FaceRec): Add `is_default_instance' member. * src/sfnt/sfobjs.c (sfnt_init_face): Initialize `is_default_instance'. * src/truetype/ttgload.c (TT_Process_Simple_Glyph, load_truetype_glyph): Add test for default instance. (TT_Load_Glyph): Load embedded bitmaps for default instance only. * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Compute `is_default_instance'.

diff --git a/ChangeLog b/ChangeLog
index 1f4ae74..311168f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2016-09-29  Werner Lemberg  <wl@gnu.org>
 
+	[truetype] Disallow bitmap strokes for non-default instances.
+
+	Also speed up access of default instances if GX variations are
+	active.
+
+	* include/freetype/internal/tttypes.h (TT_FaceRec): Add
+	`is_default_instance' member.
+
+	* src/sfnt/sfobjs.c (sfnt_init_face): Initialize
+	`is_default_instance'.
+
+	* src/truetype/ttgload.c (TT_Process_Simple_Glyph,
+	load_truetype_glyph): Add test for default instance.
+	(TT_Load_Glyph): Load embedded bitmaps for default instance only.
+
+	* src/truetype/ttgxvar.c (TT_Set_MM_Blend): Compute
+	`is_default_instance'.
+
+2016-09-29  Werner Lemberg  <wl@gnu.org>
+
 	[truetype] Clean up `TT_Face' structure.
 
 	* include/freetype/internal/tttypes.h (TT_FaceRec): Remove unused
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 01bfa56..f9079ba 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1302,6 +1302,10 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    ebdt_size            :: The size of the sbit data table.           */
   /*                                                                       */
+  /*    is_default_instance  :: Set if the glyph outlines can be used      */
+  /*                            unmodified (i.e., without applying glyph   */
+  /*                            variation deltas).                         */
+  /*                                                                       */
   typedef struct  TT_FaceRec_
   {
     FT_FaceRec            root;
@@ -1455,6 +1459,9 @@ FT_BEGIN_HEADER
     FT_ULong              ebdt_size;
 #endif
 
+    /* since 2.7.1 */
+    FT_Bool               is_default_instance;
+
   } TT_FaceRec;
 
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index ac0f5ed..8f9b878 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -901,6 +901,8 @@
     if ( error )
       return error;
 
+    face->is_default_instance = 1;
+
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     {
       FT_ULong  fvar_len;
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 17d3036..d3e763b 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -886,7 +886,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-    if ( loader->face->doblend )
+    if ( loader->face->doblend && !loader->face->is_default_instance )
     {
       /* Deltas apply to the unscaled data. */
       error = TT_Vary_Apply_Glyph_Deltas( loader->face,
@@ -1564,7 +1564,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-      if ( loader->face->doblend )
+      if ( loader->face->doblend && !loader->face->is_default_instance )
       {
         /* a small outline structure with four elements for */
         /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
@@ -1727,7 +1727,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-      if ( face->doblend )
+      if ( face->doblend && !face->is_default_instance )
       {
         short        i, limit;
         FT_SubGlyph  subglyph;
@@ -2566,18 +2566,17 @@
   {
     FT_Error      error;
     TT_LoaderRec  loader;
+    TT_Face       face = (TT_Face)glyph->face;
 
 
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-    /* try to load embedded bitmap if any              */
-    /*                                                 */
-    /* XXX: The convention should be emphasized in     */
-    /*      the documents because it can be confusing. */
+    /* try to load embedded bitmap (if any) */
     if ( size->strike_index != 0xFFFFFFFFUL      &&
-         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
+         face->is_default_instance               )
     {
       error = load_sbit_image( size, glyph, glyph_index, load_flags );
       if ( !error )
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index c0d013c..b82b2d8 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1051,6 +1051,7 @@
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
     FT_UInt     i;
+    FT_Bool     is_default_instance = 1;
     FT_Memory   memory = face->root.memory;
 
     enum
@@ -1093,6 +1094,9 @@
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
+
+      if ( coords[i] != 0 )
+        is_default_instance = 0;
     }
 
     FT_TRACE5(( "\n" ));
@@ -1172,6 +1176,8 @@
       }
     }
 
+    face->is_default_instance = is_default_instance;
+
   Exit:
     return error;
   }