[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.
This commit is contained in:
Werner Lemberg 2023-04-26 12:03:04 +02:00
parent fdcb14a2ee
commit 6713b1e41a
6 changed files with 49 additions and 46 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}