Commit 08cd62deedefe217f2ea50e392923ce8b5bc7ac7

Werner Lemberg 2017-12-20T22:06:19

Speed up FT_Set_Var_{Design,Blend}_Coordinates if curr == new. We exit early if the current design or blend coordinates are identical to the new ones. * src/truetype/ttgxvar.c (tt_set_mm_blend, TT_Set_Var_Design): Implement it, returning internal error code -1 if there will be no variation change. * src/type1/t1load.c (t1_set_mm_blend): Ditto. * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Updated.

diff --git a/ChangeLog b/ChangeLog
index 080f03e..e19cb50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2017-12-20  Werner Lemberg  <wl@gnu.org>
+
+	Speed up FT_Set_Var_{Design,Blend}_Coordinates if curr == new.
+
+	We exit early if the current design or blend coordinates are
+	identical to the new ones.
+
+	* src/truetype/ttgxvar.c (tt_set_mm_blend, TT_Set_Var_Design):
+	Implement it, returning internal error code -1 if there will be no
+	variation change.
+
+	* src/type1/t1load.c (t1_set_mm_blend): Ditto.
+
+	* src/base/ftmm.c (FT_Set_Var_Design_Coordinates,
+	FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Updated.
+
 2017-12-18  Werner Lemberg  <wl@gnu.org>
 
 	[sfnt] Fix charmap type 2 iterator (#52646).
diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
index a934f94..a92ae34 100644
--- a/include/freetype/internal/services/svmm.h
+++ b/include/freetype/internal/services/svmm.h
@@ -48,11 +48,15 @@ FT_BEGIN_HEADER
                             FT_UInt   num_coords,
                             FT_Long*  coords );
 
+  /* use return value -1 to indicate that the new coordinates  */
+  /* are equal to the current ones; no changes are thus needed */
   typedef FT_Error
   (*FT_Set_Var_Design_Func)( FT_Face    face,
                              FT_UInt    num_coords,
                              FT_Fixed*  coords );
 
+  /* use return value -1 to indicate that the new coordinates  */
+  /* are equal to the current ones; no changes are thus needed */
   typedef FT_Error
   (*FT_Set_MM_Blend_Func)( FT_Face   face,
                            FT_UInt   num_coords,
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index e0131ec..6a42df6 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -203,6 +203,10 @@
       error = FT_ERR( Invalid_Argument );
       if ( service_mm->set_var_design )
         error = service_mm->set_var_design( face, num_coords, coords );
+
+      /* internal error code -1 means `no change'; we can exit immediately */
+      if ( error == -1 )
+        return FT_Err_Ok;
     }
 
     if ( !error )
@@ -275,6 +279,10 @@
       error = FT_ERR( Invalid_Argument );
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
+
+      /* internal error code -1 means `no change'; we can exit immediately */
+      if ( error == -1 )
+        return FT_Err_Ok;
     }
 
     if ( !error )
@@ -322,6 +330,10 @@
       error = FT_ERR( Invalid_Argument );
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
+
+      /* internal error code -1 means `no change'; we can exit immediately */
+      if ( error == -1 )
+        return FT_Err_Ok;
     }
 
     if ( !error )
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 8230419..2acd7e0 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -2432,6 +2432,12 @@
     }
     else
     {
+      FT_Bool    have_diff = 0;
+      FT_UInt    j;
+      FT_Fixed*  c;
+      FT_Fixed*  n;
+
+
       manageCvt = mcvt_retain;
 
       for ( i = 0; i < num_coords; i++ )
@@ -2439,10 +2445,34 @@
         if ( blend->normalizedcoords[i] != coords[i] )
         {
           manageCvt = mcvt_load;
+          have_diff = 1;
           break;
         }
       }
 
+      if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+      {
+        FT_UInt  idx = (FT_UInt)face->root.face_index >> 16;
+
+
+        c = blend->normalizedcoords + i;
+        n = blend->normalized_stylecoords + idx * mmvar->num_axis + i;
+        for ( j = i; j < mmvar->num_axis; j++, n++, c++ )
+          if ( *c != *n )
+            have_diff = 1;
+      }
+      else
+      {
+        c = blend->normalizedcoords + i;
+        for ( j = i; j < mmvar->num_axis; j++, c++ )
+          if ( *c != 0 )
+            have_diff = 1;
+      }
+
+      /* return value -1 indicates `no change' */
+      if ( !have_diff )
+        return -1;
+
       for ( ; i < mmvar->num_axis; i++ )
       {
         if ( blend->normalizedcoords[i] != 0 )
@@ -2664,8 +2694,11 @@
     FT_Memory   memory = face->root.memory;
 
     FT_Fixed*  c;
+    FT_Fixed*  n;
     FT_Fixed*  normalized = NULL;
 
+    FT_Bool  have_diff = 0;
+
 
     if ( !face->blend )
     {
@@ -2690,25 +2723,35 @@
         goto Exit;
     }
 
-    FT_MEM_COPY( blend->coords,
-                 coords,
-                 num_coords * sizeof ( FT_Fixed ) );
-
-    c = blend->coords + num_coords;
+    c = blend->coords;
+    n = coords;
+    for ( i = 0; i < num_coords; i++, n++, c++ )
+    {
+      if ( *c != *n )
+      {
+        *c        = *n;
+        have_diff = 1;
+      }
+    }
 
     if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
     {
       FT_UInt              instance_index;
       FT_Var_Named_Style*  named_style;
-      FT_Fixed*            n;
 
 
       instance_index = (FT_UInt)face->root.face_index >> 16;
       named_style    = mmvar->namedstyle + instance_index - 1;
 
       n = named_style->coords + num_coords;
-      for ( i = num_coords; i < mmvar->num_axis; i++, n++, c++ )
-        *c = *n;
+      for ( ; i < mmvar->num_axis; i++, n++, c++ )
+      {
+        if ( *c != *n )
+        {
+          *c        = *n;
+          have_diff = 1;
+        }
+      }
     }
     else
     {
@@ -2716,10 +2759,20 @@
 
 
       a = mmvar->axis + num_coords;
-      for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ )
-        *c = a->def;
+      for ( ; i < mmvar->num_axis; i++, a++, c++ )
+      {
+        if ( *c != a->def )
+        {
+          *c        = a->def;
+          have_diff = 1;
+        }
+      }
     }
 
+    /* return value -1 indicates `no change' */
+    if ( !have_diff )
+      return -1;
+
     if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
       goto Exit;
 
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index bdb986a..70e7c68 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -374,6 +374,8 @@
     PS_Blend  blend = face->blend;
     FT_UInt   n, m;
 
+    FT_Bool  have_diff = 0;
+
 
     if ( !blend )
       return FT_THROW( Invalid_Argument );
@@ -405,10 +407,16 @@
 
         result = FT_MulFix( result, factor );
       }
-      blend->weight_vector[n] = result;
+
+      if ( blend->weight_vector[n] != result )
+      {
+        blend->weight_vector[n] = result;
+        have_diff               = 1;
+      }
     }
 
-    return FT_Err_Ok;
+    /* return value -1 indicates `no change' */
+    return have_diff ? FT_Err_Ok : -1;
   }