summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Röttsches <drott@chromium.org>2022-06-29 16:01:13 +0300
committerWerner Lemberg <wl@gnu.org>2022-07-04 16:34:02 +0200
commit31b14fd4dce4b017090f5ba7c15a178fa0ce6d7d (patch)
tree5f63ca5bc1544b8282695b0490bf149b12be219f
parent1a242558be670626ed2ec62efb1909c000b2cae7 (diff)
downloadfreetype2-31b14fd4dce4b017090f5ba7c15a178fa0ce6d7d.tar.gz
[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.
-rw-r--r--src/sfnt/ttcolr.c100
1 files changed, 100 insertions, 0 deletions
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 );
}