Commit 7838c78f53f206ac5b8e9cefde548aa81cb00cf4

Dominik Röttsches 2022-05-20T17:22:25

[truetype] Support reading 32bit/16bit VarStore deltas * include/freetype/internal/ftmmtypes.h (FT_ItemVarDelta): Define type to be used for delta arrays, upgrade to FT_long. * src/truetype/ttgxvar.c: Adhere to long_words bit and read either Short/Byte pairs or Long/Short pairs, as defined by spec. For better readability, define macro for repetitive read code.

diff --git a/include/freetype/internal/ftmmtypes.h b/include/freetype/internal/ftmmtypes.h
index 74706be..44f7e74 100644
--- a/include/freetype/internal/ftmmtypes.h
+++ b/include/freetype/internal/ftmmtypes.h
@@ -24,14 +24,16 @@
 FT_BEGIN_HEADER
 
 
+  typedef FT_Long FT_ItemVarDelta;
+
   typedef struct  GX_ItemVarDataRec_
   {
-    FT_UInt    itemCount;      /* number of delta sets per item         */
-    FT_UInt    regionIdxCount; /* number of region indices in this data */
-    FT_UInt*   regionIndices;  /* array of `regionCount' indices;       */
-                               /* these index `varRegionList'           */
-    FT_Short*  deltaSet;       /* array of `itemCount' deltas           */
-                               /* use `innerIndex' for this array       */
+    FT_UInt            itemCount;       /* number of delta sets per item    */
+    FT_UInt            regionIdxCount;  /* number of region indices         */
+    FT_UInt*           regionIndices;   /* array of `regionCount' indices;  */
+                                        /* these index `varRegionList'      */
+    FT_ItemVarDelta*   deltaSet;        /* array of `itemCount' deltas      */
+                                        /* use `innerIndex' for this array  */
 
   } GX_ItemVarDataRec, *GX_ItemVarData;
 
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index d6a34e3..36f70c8 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -631,44 +631,25 @@
                          varData->regionIdxCount * varData->itemCount ) )
         goto Exit;
 
-      /* the delta set is stored as a 2-dimensional array of shorts */
-      if ( long_words )
+      for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
       {
-        /* new in OpenType 1.9, currently for 'COLR' table only;          */
-        /* the deltas are interpreted as 16.16 fixed-point scaling values */
-
-        /* not supported yet */
-
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-      else
-      {
-        for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
+        if ( long_words )
         {
           for ( k = 0; k < wordDeltaCount; k++, j++ )
-          {
-            /* read the short deltas */
-            FT_Short  delta;
-
-
-            if ( FT_READ_SHORT( delta ) )
+            if ( FT_READ_LONG( varData->deltaSet[j] ) )
               goto Exit;
-
-            varData->deltaSet[j] = delta;
-          }
-
           for ( ; k < varData->regionIdxCount; k++, j++ )
-          {
-            /* read the (signed) byte deltas */
-            FT_Char  delta;
-
-
-            if ( FT_READ_CHAR( delta ) )
+            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
+              goto Exit;
+        }
+        else
+        {
+          for ( k = 0; k < wordDeltaCount; k++, j++ )
+            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
+              goto Exit;
+          for ( ; k < varData->regionIdxCount; k++, j++ )
+            if ( FT_READ_CHAR( varData->deltaSet[j] ) )
               goto Exit;
-
-            varData->deltaSet[j] = delta;
-          }
         }
       }
     }
@@ -964,8 +945,8 @@
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex )
   {
-    GX_ItemVarData  varData;
-    FT_Short*       deltaSet;
+    GX_ItemVarData    varData;
+    FT_ItemVarDelta*  deltaSet;
 
     FT_UInt   master, j;
     FT_Fixed  netAdjustment = 0;     /* accumulated adjustment */