From 472ac82a615692a52114e2546991add30d18960c Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 26 Apr 2023 12:03:04 +0200 Subject: [truetype] Fix deactivation of variation font handling. According to the documentation, the functions `FT_Set_Named_Instance`, `FT_Set_MM_Design_Coordinates`, `FT_Set_Var_Design_Coordinates`, and `FT_Set_Var_Blend_Coordinates` can unset the `FT_FACE_FLAG_VARIATION` flag. (The same is true for `FT_Set_MM_WeightVector` but this information was accidentally omitted from the documentation.) However, if a call of these functions didn't change the axis values this could fail because internal shortcuts exited too early. This commit reorganizes the code to handle `FT_FACE_FLAG_VARIATION` in the top-level API functions, also taking care of the issue at hand. * src/base/ftmm.c (FT_Set_MM_Design_Coordinates, FT_Set_MM_WeightVector, FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Handle `FT_FACE_FLAG_VARIATION`. * src/truetype/ttgxvar.c (TT_Set_MM_Blend, TT_Set_Var_Design, TT_Set_Named_Instance) Don't handle `FT_FACE_FLAG_VARIATION`. * src/type1/t1load.c (T1_Set_MM_Blend, T1_Set_MM_WeightVector, T1_Set_MM_Design): Ditto. * src/cff/cffobjs.c (cff_face_init): Use `FT_Set_Named_Instance` instead of low-level functions. * src/truetype/ttobjs.c (tt_face_init): Ditto. --- include/freetype/ftmm.h | 8 +++++--- src/base/ftmm.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/cff/cffobjs.c | 11 +---------- src/truetype/ttgxvar.c | 15 ++------------- src/truetype/ttobjs.c | 6 +----- src/type1/t1load.c | 15 --------------- 6 files changed, 49 insertions(+), 46 deletions(-) diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index 2c2f165fa..d145128a9 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -602,10 +602,12 @@ FT_BEGIN_HEADER * * @note: * Adobe Multiple Master fonts limit the number of designs, and thus the - * length of the weight vector to~16. + * length of the weight vector to 16~elements. * - * If `len` is zero and `weightvector` is `NULL`, the weight vector array - * is reset to the default values. + * If `len` is larger than zero, this function sets the + * @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field (i.e., + * @FT_IS_VARIATION will return true). If `len` is zero, this bit flag + * is unset and the weight vector array is reset to the default values. * * The Adobe documentation also states that the values in the * WeightVector array must total 1.0 +/-~0.001. In practice this does diff --git a/src/base/ftmm.c b/src/base/ftmm.c index 1d5e2bcca..c061431a4 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -185,6 +185,14 @@ error = FT_ERR( Invalid_Argument ); if ( service->set_mm_design ) error = service->set_mm_design( face, num_coords, coords ); + + if ( !error ) + { + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } } /* enforce recomputation of auto-hinting data */ @@ -220,6 +228,14 @@ error = FT_ERR( Invalid_Argument ); if ( service->set_mm_weightvector ) error = service->set_mm_weightvector( face, len, weightvector ); + + if ( !error ) + { + if ( len ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } } /* enforce recomputation of auto-hinting data */ @@ -283,6 +299,14 @@ if ( service_mm->set_var_design ) error = service_mm->set_var_design( face, num_coords, coords ); + if ( !error || error == -1 ) + { + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; @@ -359,6 +383,14 @@ if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + if ( !error || error == -1 ) + { + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; @@ -410,6 +442,14 @@ if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + if ( !error || error == -1 ) + { + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index 2285c1a48..1f24f3d91 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -719,24 +719,15 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Service_MultiMasters - mm = (FT_Service_MultiMasters)face->mm; - FT_Service_MetricsVariations - var = (FT_Service_MetricsVariations)face->face_var; - FT_UInt instance_index = (FT_UInt)face_index >> 16; if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && - mm && instance_index > 0 ) { - error = mm->set_named_instance( cffface, instance_index ); + error = FT_Set_Named_Instance( cffface, instance_index ); if ( error ) goto Exit; - - if ( var ) - var->metrics_adjust( cffface ); } } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index d28cc245e..44483625a 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2985,11 +2985,6 @@ if ( error ) return error; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - return FT_Err_Ok; } @@ -3208,11 +3203,6 @@ if ( error ) goto Exit; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - Exit: FT_FREE( normalized ); return error; @@ -3382,9 +3372,8 @@ else error = TT_Set_Var_Design( face, 0, NULL ); - face->root.face_index = ( instance_index << 16 ) | - ( face->root.face_index & 0xFFFFL ); - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + face->root.face_index = ( instance_index << 16 ) | + ( face->root.face_index & 0xFFFFL ); Exit: return error; diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index c351e082b..29d41da07 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -777,7 +777,6 @@ } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_UInt instance_index = (FT_UInt)face_index >> 16; @@ -785,14 +784,11 @@ if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && instance_index > 0 ) { - error = TT_Set_Named_Instance( face, instance_index ); + error = FT_Set_Named_Instance( ttface, instance_index ); if ( error ) goto Exit; - - tt_apply_mvar( face ); } } - #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* initialize standard glyph loading routines */ diff --git a/src/type1/t1load.c b/src/type1/t1load.c index 371edf4c1..a3b281009 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -449,11 +449,6 @@ if ( error ) return error; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - return FT_Err_Ok; } @@ -522,11 +517,6 @@ for ( ; i < blend->num_designs; i++ ) blend->weight_vector[i] = (FT_Fixed)0; - - if ( len ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; } return FT_Err_Ok; @@ -638,11 +628,6 @@ if ( error ) return error; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - return FT_Err_Ok; } -- cgit v1.2.1