From fb982e78a7d4468aa55ae2b560f0213d289c52fa Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 26 Apr 2023 08:17:17 +0200 Subject: New Variation Font function `FT_Get_Default_Named_Instance`. * include/freetype/ftmm.h, src/base/ftmm.c (FT_Get_Default_Named_Instance): New function. * include/freetype/internal/services/svmm.h (FT_Get_Default_Named_Instance_Func): New typedef. (FT_Service_MultiMasters): New field `get_default_named_instance`. (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. * include/freetype/internal/tttypes.h (TT_Face): New field `var_default_named_instance`. * src/sfnt/sfobjc.s (sfnt_init_face): Initialize `var_default_named_instance`. * src/cff/cffdrivr.c (cff_get_default_named_instance): New function. (cff_service_multi_masters): Updated. * src/truetype/ttgxvar.c (TT_Get_MM_Var): Initialize `var_default_named_instance`. (TT_Get_Default_Named_Instance): New function. * src/truetype/ttgxvar.h: Updated. * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated. * src/type1/t1driver.c (t1_service_multi_masters): Updated. * docs/CHANGES: Updated. --- docs/CHANGES | 12 ++++- include/freetype/ftmm.h | 39 +++++++++++++++ include/freetype/internal/services/svmm.h | 81 +++++++++++++++++-------------- include/freetype/internal/tttypes.h | 4 ++ src/base/ftmm.c | 28 +++++++++++ src/cff/cffdrivr.c | 48 +++++++++++------- src/sfnt/sfobjs.c | 3 ++ src/truetype/ttdriver.c | 37 +++++++------- src/truetype/ttgxvar.c | 48 +++++++++++++++++- src/truetype/ttgxvar.h | 4 ++ src/type1/t1driver.c | 36 +++++++------- 11 files changed, 249 insertions(+), 91 deletions(-) diff --git a/docs/CHANGES b/docs/CHANGES index bc85f9d57..105f976e8 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -1,3 +1,13 @@ +CHANGES BETWEEN 2.13.0 and 2.13.1 (2023-XXX-XX) + + I. MISCELLANEOUS + + - New function `FT_Get_Default_Named_Instance` to get the index of + the default named instance of an OpenType Variation Font. + + +====================================================================== + CHANGES BETWEEN 2.12.1 and 2.13.0 (2023-Feb-09) I. IMPORTANT CHANGES @@ -12,7 +22,7 @@ CHANGES BETWEEN 2.12.1 and 2.13.0 (2023-Feb-09) https://learn.microsoft.com/en-us/typography/opentype/spec/colr - III. MISCELLANEOUS + II. MISCELLANEOUS - For OpenType Variable Fonts, `avar` table format 2.0 is now supported. The code was contributed by Behdad Esfahbod. diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index 3eabdd5f2..2c2f165fa 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -753,6 +753,45 @@ FT_BEGIN_HEADER FT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); + + /************************************************************************** + * + * @function: + * FT_Get_Default_Named_Instance + * + * @description: + * Retrieve the index of the default named instance, to be used with + * @FT_Set_Named_Instance. + * + * The default instance of a variation font is that instance for which + * the nth axis coordinate is equal to `axis[n].def` (as specified in the + * @FT_MM_Var structure), with~n covering all axes. + * + * FreeType synthesizes a named instance for the default instance if the + * font does not contain such an entry. + * + * @input: + * face :: + * A handle to the source face. + * + * @output: + * instance_index :: + * The index of the default named instance. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * For Adobe MM fonts (which don't have named instances) this function + * always returns zero for `instance_index`. + * + * @since: + * 2.13.1 + */ + FT_EXPORT( FT_Error ) + FT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ); + /* */ diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h index d94204232..f87b8acf7 100644 --- a/include/freetype/internal/services/svmm.h +++ b/include/freetype/internal/services/svmm.h @@ -73,6 +73,10 @@ FT_BEGIN_HEADER (*FT_Set_Instance_Func)( FT_Face face, FT_UInt instance_index ); + typedef FT_Error + (*FT_Get_Default_Named_Instance_Func)( FT_Face face, + FT_UInt *instance_index ); + typedef FT_Error (*FT_Get_MM_Blend_Func)( FT_Face face, FT_UInt num_coords, @@ -135,6 +139,7 @@ FT_BEGIN_HEADER FT_Set_Var_Design_Func set_var_design; FT_Get_Var_Design_Func get_var_design; FT_Set_Instance_Func set_instance; + FT_Get_Default_Named_Instance_Func get_default_named_instance; FT_Set_MM_WeightVector_Func set_mm_weightvector; FT_Get_MM_WeightVector_Func get_mm_weightvector; @@ -149,43 +154,45 @@ FT_BEGIN_HEADER }; -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - set_weightvector_, \ - get_weightvector_, \ - load_delta_set_idx_map_, \ - load_item_var_store_, \ - get_item_delta_, \ - done_item_var_store_, \ - done_delta_set_idx_map_, \ - get_var_blend_, \ - done_blend_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - set_weightvector_, \ - get_weightvector_, \ - load_delta_set_idx_map_, \ - load_item_var_store_, \ - get_item_delta_, \ - done_item_var_store_, \ - done_delta_set_idx_map_, \ - get_var_blend_, \ - done_blend_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + get_default_named_instance_, \ + set_weightvector_, \ + get_weightvector_, \ + load_delta_set_idx_map_, \ + load_item_var_store_, \ + get_item_delta_, \ + done_item_var_store_, \ + done_delta_set_idx_map_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + get_default_named_instance_, \ + set_weightvector_, \ + get_weightvector_, \ + load_delta_set_idx_map_, \ + load_item_var_store_, \ + get_item_delta_, \ + done_item_var_store_, \ + done_delta_set_idx_map_, \ + get_var_blend_, \ + done_blend_ \ }; /* */ diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index af6830a4d..10af061b9 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1315,6 +1315,9 @@ FT_BEGIN_HEADER * var_postscript_prefix_len :: * The length of the `var_postscript_prefix` string. * + * var_default_named_instance :: + * The index of the default named instance. + * * horz_metrics_size :: * The size of the 'hmtx' table. * @@ -1552,6 +1555,7 @@ FT_BEGIN_HEADER const char* var_postscript_prefix; /* since 2.7.2 */ FT_UInt var_postscript_prefix_len; /* since 2.7.2 */ + FT_UInt var_default_named_instance; /* since 2.13.1 */ #endif /* since version 2.2 */ diff --git a/src/base/ftmm.c b/src/base/ftmm.c index a2b4bd03d..781db315e 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -565,4 +565,32 @@ } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ) + { + FT_Error error; + + FT_Service_MultiMasters service_mm = NULL; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + /* no error if `get_default_named_instance` is not available */ + if ( service_mm->get_default_named_instance ) + error = service_mm->get_default_named_instance( face, + instance_index ); + else + error = FT_Err_Ok; + } + + return error; + } + + /* END */ diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 7d45e4641..d9ed35b2b 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -942,6 +942,17 @@ } + static FT_Error + cff_get_default_named_instance( CFF_Face face, + FT_UInt *instance_index ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_default_named_instance( FT_FACE( face ), instance_index ); + } + + static FT_Error cff_load_item_variation_store( CFF_Face face, FT_ULong offset, @@ -1009,36 +1020,39 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( cff_service_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ - (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ - (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ - (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ + (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ + (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ + (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ + (FT_Get_Default_Named_Instance_Func) + cff_get_default_named_instance, + /* get_default_named_instance */ (FT_Set_MM_WeightVector_Func) cff_set_mm_weightvector, - /* set_mm_weightvector */ + /* set_mm_weightvector */ (FT_Get_MM_WeightVector_Func) cff_get_mm_weightvector, - /* get_mm_weightvector */ + /* get_mm_weightvector */ (FT_Var_Load_Delta_Set_Idx_Map_Func) cff_load_delta_set_index_mapping, - /* load_delta_set_idx_map */ + /* load_delta_set_idx_map */ (FT_Var_Load_Item_Var_Store_Func) cff_load_item_variation_store, - /* load_item_variation_store */ + /* load_item_variation_store */ (FT_Var_Get_Item_Delta_Func) - cff_get_item_delta, /* get_item_delta */ + cff_get_item_delta, /* get_item_delta */ (FT_Var_Done_Item_Var_Store_Func) cff_done_item_variation_store, - /* done_item_variation_store */ + /* done_item_variation_store */ (FT_Var_Done_Delta_Set_Idx_Map_Func) cff_done_delta_set_index_map, - /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + /* done_delta_set_index_map */ + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ ) diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 13f2f45f4..1574c353d 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -698,6 +698,9 @@ instance_offset += instance_size; } + /* named instance indices start with value 1 */ + face->var_default_named_instance = i + 1; + if ( i == num_instances ) { /* no default instance in named instance table; */ diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index c2e041cd3..c128be19d 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -517,34 +517,37 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ + (FT_Get_Default_Named_Instance_Func) + TT_Get_Default_Named_Instance, + /* get_default_named_instance */ (FT_Set_MM_WeightVector_Func) - NULL, /* set_mm_weightvector */ + NULL, /* set_mm_weightvector */ (FT_Get_MM_WeightVector_Func) - NULL, /* get_mm_weightvector */ + NULL, /* get_mm_weightvector */ (FT_Var_Load_Delta_Set_Idx_Map_Func) tt_var_load_delta_set_index_mapping, - /* load_delta_set_idx_map */ + /* load_delta_set_idx_map */ (FT_Var_Load_Item_Var_Store_Func) tt_var_load_item_variation_store, - /* load_item_variation_store */ + /* load_item_variation_store */ (FT_Var_Get_Item_Delta_Func) - tt_var_get_item_delta, /* get_item_delta */ + tt_var_get_item_delta, /* get_item_delta */ (FT_Var_Done_Item_Var_Store_Func) tt_var_done_item_variation_store, - /* done_item_variation_store */ + /* done_item_variation_store */ (FT_Var_Done_Delta_Set_Idx_Map_Func) tt_var_done_delta_set_index_map, - /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + /* done_delta_set_index_map */ + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ ) FT_DEFINE_SERVICE_METRICSVARIATIONSREC( diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 963dcb7e3..d28cc245e 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2630,8 +2630,10 @@ FT_UInt strid = ~0U; - /* the default instance is missing in array the */ - /* of named instances; try to synthesize an entry */ + /* The default instance is missing in array the */ + /* of named instances; try to synthesize an entry. */ + /* If this fails, `default_named_instance` remains */ + /* at value zero, which doesn't do any harm. */ found = sfnt->get_name_id( face, TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, &dummy1, @@ -2659,6 +2661,9 @@ FT_TRACE5(( "TT_Get_MM_Var:" " Adding default instance to named instances\n" )); + /* named instance indices start with value 1 */ + face->var_default_named_instance = num_instances; + ns = &mmvar->namedstyle[fvar_head.instanceCount]; ns->strid = strid; @@ -3386,6 +3391,45 @@ } + /************************************************************************** + * + * @Function: + * TT_Get_Default_Named_Instance + * + * @Description: + * Get the default named instance. + * + * @Input: + * face :: + * A handle to the source face. + * + * @Output: + * instance_index :: + * The default named instance index. + * + * @Return: + * FreeType error code. 0~means success. + */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_Default_Named_Instance( TT_Face face, + FT_UInt *instance_index ) + { + FT_Error error = FT_Err_Ok; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } + + *instance_index = face->var_default_named_instance; + + Exit: + return error; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 4fec980dc..0c096f7df 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -374,6 +374,10 @@ FT_BEGIN_HEADER TT_Set_Named_Instance( TT_Face face, FT_UInt instance_index ); + FT_LOCAL( FT_Error ) + TT_Get_Default_Named_Instance( TT_Face face, + FT_UInt *instance_index ); + FT_LOCAL( FT_Error ) tt_face_vary_cvt( TT_Face face, FT_Stream stream ); diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index ded3b264e..5d0fe533c 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -121,30 +121,32 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ - (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ + (FT_Get_Default_Named_Instance_Func) + NULL, /* get_default_named_instance */ (FT_Set_MM_WeightVector_Func) - T1_Set_MM_WeightVector, /* set_mm_weightvector */ + T1_Set_MM_WeightVector, /* set_mm_weightvector */ (FT_Get_MM_WeightVector_Func) - T1_Get_MM_WeightVector, /* get_mm_weightvector */ + T1_Get_MM_WeightVector, /* get_mm_weightvector */ (FT_Var_Load_Delta_Set_Idx_Map_Func) - NULL, /* load_delta_set_idx_map */ + NULL, /* load_delta_set_idx_map */ (FT_Var_Load_Item_Var_Store_Func) - NULL, /* load_item_variation_store */ + NULL, /* load_item_variation_store */ (FT_Var_Get_Item_Delta_Func) - NULL, /* get_item_delta */ + NULL, /* get_item_delta */ (FT_Var_Done_Item_Var_Store_Func) - NULL, /* done_item_variation_store */ + NULL, /* done_item_variation_store */ (FT_Var_Done_Delta_Set_Idx_Map_Func) - NULL, /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ - (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ + NULL, /* done_delta_set_index_map */ + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif -- cgit v1.2.1