freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 31b14fd4d: [sfnt] Load variation store for 'COLR' v1.


From: Werner Lemberg
Subject: [freetype2] master 31b14fd4d: [sfnt] Load variation store for 'COLR' v1.
Date: Mon, 4 Jul 2022 10:34:40 -0400 (EDT)

branch: master
commit 31b14fd4dce4b017090f5ba7c15a178fa0ce6d7d
Author: Dominik Röttsches <drott@chromium.org>
Commit: Werner Lemberg <wl@gnu.org>

    [sfnt] Load variation store for 'COLR' v1.
    
    * src/sfnt/ttcolr.c: Include `ttobjs.h` temporarily.
    (VARIABLE_COLRV1_ENABLED): New temporary macro to detect whether variable
    COLRv1 is enabled.
    (Colr): New fields `var_store` and `delta_set_idx_map`.
    (tt_face_load_colr, tt_face_free_colr) [VARIABLE_COLRV1_ENABLED]: Load and
    free variation store data using the functions from the Multiple Masters
    service.
---
 src/sfnt/ttcolr.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index e02dd060e..c7232e1fc 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -30,10 +30,15 @@
 #include <freetype/internal/ftcalc.h>
 #include <freetype/internal/ftdebug.h>
 #include <freetype/internal/ftstream.h>
+#include <freetype/internal/services/svmm.h>
 #include <freetype/tttags.h>
 #include <freetype/ftcolor.h>
 #include <freetype/config/integer-types.h>
 
+ /* the next code line is a temporary hack, to be removed together with */
+ /* `VARIABLE_COLRV1_ENABLED` and related code                          */
+#include "../truetype/ttobjs.h"
+
 
 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
 
@@ -50,6 +55,10 @@
 #define COLR_HEADER_SIZE                 14U
 
 
+#define VARIABLE_COLRV1_ENABLED                                           \
+          ( ((TT_Driver)FT_FACE_DRIVER( face ))->enable_variable_colrv1 )
+
+
   typedef enum  FT_PaintFormat_Internal_
   {
     FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER         = 18,
@@ -104,6 +113,10 @@
      */
     FT_Byte*  paints_start_v1;
 
+    /* Item Variation Store for variable 'COLR' v1. */
+    GX_ItemVarStoreRec    var_store;
+    GX_DeltaSetIdxMapRec  delta_set_idx_map;
+
     /* The memory that backs up the `COLR' table. */
     void*     table;
     FT_ULong  table_size;
@@ -138,7 +151,9 @@
     FT_ULong  base_glyph_offset, layer_offset;
     FT_ULong  base_glyphs_offset_v1, num_base_glyphs_v1;
     FT_ULong  layer_offset_v1, num_layers_v1, clip_list_offset;
+    FT_ULong  var_idx_map_offset, var_store_offset;
     FT_ULong  table_size;
+    FT_ULong  colr_offset_in_stream;
 
 
     /* `COLR' always needs `CPAL' */
@@ -149,6 +164,8 @@
     if ( error )
       goto NoColr;
 
+    colr_offset_in_stream = FT_STREAM_POS();
+
     if ( table_size < COLR_HEADER_SIZE )
       goto InvalidTable;
 
@@ -239,6 +256,64 @@
         colr->clip_list = (FT_Byte*)( table + clip_list_offset );
       else
         colr->clip_list = 0;
+
+      colr->var_store.dataCount     = 0;
+      colr->var_store.varData       = NULL;
+      colr->var_store.axisCount     = 0;
+      colr->var_store.regionCount   = 0;
+      colr->var_store.varRegionList = 0;
+
+      colr->delta_set_idx_map.mapCount   = 0;
+      colr->delta_set_idx_map.outerIndex = NULL;
+      colr->delta_set_idx_map.innerIndex = NULL;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR &&
+           VARIABLE_COLRV1_ENABLED                         )
+      {
+        FT_Service_MultiMasters  mm  = (FT_Service_MultiMasters)face->mm;
+
+
+        var_idx_map_offset = FT_NEXT_ULONG( p );
+
+        if ( var_idx_map_offset >= table_size )
+          goto InvalidTable;
+
+        var_store_offset = FT_NEXT_ULONG( p );
+        if ( var_store_offset >= table_size )
+          goto InvalidTable;
+
+        if ( var_store_offset )
+        {
+          /* If variation info has not been initialized yet, try doing so, */
+          /* otherwise loading the variation store will fail as it         */
+          /* requires access to `blend` for checking the number of axes.   */
+          if ( !face->blend )
+            if ( mm->get_mm_var( FT_FACE( face ), NULL ) )
+              goto InvalidTable;
+
+          /* Try loading `VarIdxMap` and `VarStore`. */
+          error = mm->load_item_var_store(
+                    FT_FACE( face ),
+                    colr_offset_in_stream + var_store_offset,
+                    &colr->var_store );
+          if ( error != FT_Err_Ok )
+            goto InvalidTable;
+        }
+
+        if ( colr->var_store.axisCount && var_idx_map_offset )
+        {
+          error = mm->load_delta_set_idx_map(
+                   FT_FACE( face ),
+                   colr_offset_in_stream + var_idx_map_offset,
+                   &colr->delta_set_idx_map,
+                   &colr->var_store,
+                   table_size );
+          if ( error != FT_Err_Ok )
+            goto InvalidTable;
+        }
+      }
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
     }
 
     colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
@@ -251,6 +326,19 @@
     return FT_Err_Ok;
 
   InvalidTable:
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    if ( VARIABLE_COLRV1_ENABLED )
+    {
+      FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+      mm->done_delta_set_idx_map( FT_FACE( face ),
+                                  &colr->delta_set_idx_map );
+      mm->done_item_var_store( FT_FACE( face ),
+                               &colr->var_store );
+    }
+#endif
+
     error = FT_THROW( Invalid_Table );
 
   NoColr:
@@ -272,6 +360,18 @@
 
     if ( colr )
     {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( VARIABLE_COLRV1_ENABLED )
+      {
+        FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+        mm->done_delta_set_idx_map( FT_FACE( face ),
+                                    &colr->delta_set_idx_map );
+        mm->done_item_var_store( FT_FACE( face ),
+                                 &colr->var_store );
+      }
+#endif
       FT_FRAME_RELEASE( colr->table );
       FT_FREE( colr );
     }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]