Commit 919561ca8c2a7b245644767b49d08e638d34d4eb

Dominik Röttsches 2022-07-30T12:09:21

[sfnt] Implement VarClipBox. * src/sfnt/ttcolr.c (tt_face_get_color_glyph_clipbox): Depending on the format, read `var_index_base`, then retrieve and apply scaled deltas.

diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 9a1e9a3..25051a4 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -1362,7 +1362,7 @@
     clip_list_format = FT_NEXT_BYTE ( p );
 
     /* Format byte used here to be able to upgrade ClipList for >16bit */
-    /* glyph ids; for now we can expect it to be 0.                    */
+    /* glyph ids; for now we can expect it to be 1.                    */
     if ( !( clip_list_format == 1 ) )
       return 0;
 
@@ -1390,7 +1390,7 @@
 
         format = FT_NEXT_BYTE( p1 );
 
-        if ( format > 1 )
+        if ( format > 2 )
           return 0;
 
         /* Check whether we can extract four `FWORD`. */
@@ -1410,6 +1410,34 @@
         font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
                                         face->root.size->metrics.y_scale );
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        if ( VARIABLE_COLRV1_ENABLED && format == 2 )
+        {
+          FT_ULong         var_index_base = 0;
+          /* varIndexBase offset for clipbox is 3 at most. */
+          FT_ItemVarDelta  item_deltas[4] = { 0, 0, 0, 0 };
+
+
+          /* Check whether we can extract a 32-bit VarIdxBase now. */
+          if ( p1 > limit - 4 )
+            return 0;
+
+          var_index_base = FT_NEXT_ULONG( p1 );
+
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+                                               item_deltas ) )
+            return 0;
+
+          font_clip_box.xMin +=
+              FT_MulFix( item_deltas[0], face->root.size->metrics.x_scale );
+          font_clip_box.yMin +=
+              FT_MulFix( item_deltas[1], face->root.size->metrics.y_scale );
+          font_clip_box.xMax +=
+              FT_MulFix( item_deltas[2], face->root.size->metrics.x_scale );
+          font_clip_box.yMax +=
+              FT_MulFix( item_deltas[3], face->root.size->metrics.y_scale );
+        }
+#endif
 
         /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */
         /* them.  If we we would only transform two corner points and    */