diff --git a/ChangeLog b/ChangeLog index 80e97b167..98c837407 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2017-10-07 Werner Lemberg + + [cff, truetype] Adjust behaviour of named instances. + + This commit completely separates the interaction between named + instances and variation functions. In particular, resetting the + variation returns to the current named instance (if set) and not to + the base font. + + As a side effect, variation functions no longer change the named + instance index. + + * src/cff/cffobjs.c (cff_face_init): Use MM service's `set_instance' + function. + Also apply `MVAR' table to named instances. + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Add cast. + (tt_set_mm_blend): No longer check whether requested variation + coincides with a named instance. + (TT_Set_Var_Design): Use current named instance for default + coordinates. + * src/truetype/ttobjs.c (tt_face_init): Use `TT_Set_Named_Instance'. + 2017-10-07 Werner Lemberg Make `FT_Set_Named_Instance' work. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 3499d622b..77d277ef5 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -904,6 +904,13 @@ FT_BEGIN_HEADER /* Bit 31 is always zero (this is, */ /* `face_index' is always a positive value). */ /* */ + /* [Since 2.8.2] Changing the design */ + /* coordinates with */ + /* @FT_Set_Var_Design_Coordinates or */ + /* @FT_Set_Var_Blend_Coordinates does not */ + /* influence the named instance index value */ + /* (only @FT_Set_Named_Instance does that). */ + /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ @@ -1403,6 +1410,11 @@ FT_BEGIN_HEADER * A macro that returns true whenever a face object is a named instance * of a GX or OpenType variation font. * + * [Since 2.8.2] Changing the design coordinates with + * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does + * not influence the return value of this macro (only + * @FT_Set_Named_Instance does that). + * * @since: * 2.7 * diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index fe66f2d6c..49da79606 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -323,9 +323,13 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* */ - /* To reset all axes to the default values, call the function with */ - /* `num_coords' set to zero and `coords' set to NULL (new feature in */ - /* FreeType version 2.8.1). */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* */ + /* [Since 2.8.2] If `num_coords' 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 `num_coords' */ + /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, @@ -358,9 +362,15 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* */ - /* To reset all axes to the default values, call the function with */ - /* `num_coords' set to zero and `coords' set to NULL (new feature in */ - /* FreeType version 2.8.1). */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* [Since 2.8.2] `Default values' means the currently selected named */ + /* instance (or the base font if no named instance is selected). */ + /* */ + /* [Since 2.8.2] If `num_coords' 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 `num_coords' */ + /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, @@ -430,9 +440,15 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* */ - /* To reset all axes to the default values, call the function with */ - /* `num_coords' set to zero and `coords' set to NULL (new feature in */ - /* FreeType version 2.8.1). */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* [Since 2.8.2] `Default values' means the currently selected named */ + /* instance (or the base font if no named instance is selected). */ + /* */ + /* [Since 2.8.2] If `num_coords' 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 `num_coords' */ + /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, @@ -518,6 +534,9 @@ FT_BEGIN_HEADER /* FT_VAR_AXIS_FLAG_HIDDEN :: */ /* The variation axis should not be exposed to user interfaces. */ /* */ + /* */ + /* 2.8.1 */ + /* */ #define FT_VAR_AXIS_FLAG_HIDDEN 1 diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index c794d3239..983fd2e71 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -708,50 +708,22 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; - FT_Int instance_index = face_index >> 16; + FT_UInt instance_index = (FT_UInt)face_index >> 16; if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && mm && instance_index > 0 ) { - FT_MM_Var* mm_var; - - - error = mm->get_mm_var( cffface, NULL ); + error = mm->set_instance( cffface, instance_index ); if ( error ) goto Exit; - mm->get_var_blend( cffface, NULL, NULL, NULL, &mm_var ); - - if ( mm_var->namedstyle ) - { - FT_Var_Named_Style* named_style; - FT_String* style_name; - - - /* in `face_index', the instance index starts with value 1 */ - named_style = mm_var->namedstyle + instance_index - 1; - error = sfnt->get_name( face, - (FT_UShort)named_style->strid, - &style_name ); - if ( error ) - goto Exit; - - /* set style name; if already set, replace it */ - if ( face->root.style_name ) - FT_FREE( face->root.style_name ); - face->root.style_name = style_name; - - /* finally, select the named instance */ - error = mm->set_var_design( cffface, - mm_var->num_axis, - named_style->coords ); - 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 4ad6533bf..f3c2430da 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2057,7 +2057,7 @@ /* `num_instances' holds the number of all named instances, */ /* including the default instance which might be missing */ /* in fvar's table of named instances */ - num_instances = face->root.style_flags >> 16; + num_instances = (FT_UInt)face->root.style_flags >> 16; /* prepare storage area for MM data; this cannot overflow */ /* 32-bit arithmetic because of the size limits used in the */ @@ -2348,7 +2348,7 @@ FT_Error error = FT_Err_Ok; GX_Blend blend; FT_MM_Var* mmvar; - FT_UInt i, j; + FT_UInt i; FT_Bool all_design_coords = FALSE; @@ -2489,30 +2489,6 @@ } } - /* check whether the current variation tuple coincides */ - /* with a named instance */ - - for ( i = 0; i < blend->mmvar->num_namedstyles; i++ ) - { - FT_Fixed* nsc = blend->normalized_stylecoords + i * blend->num_axis; - FT_Fixed* ns = blend->normalizedcoords; - - - for ( j = 0; j < blend->num_axis; j++, nsc++, ns++ ) - { - if ( *nsc != *ns ) - break; - } - - if ( j == blend->num_axis ) - break; - } - - /* adjust named instance index */ - face->root.face_index &= 0xFFFF; - if ( i < blend->mmvar->num_namedstyles ) - face->root.face_index |= ( i + 1 ) << 16; - /* enforce recomputation of the PostScript name; */ FT_FREE( face->postscript_name ); face->postscript_name = NULL; @@ -2680,9 +2656,7 @@ FT_UInt i; FT_Memory memory = face->root.memory; - FT_Var_Axis* a; - FT_Fixed* c; - + FT_Fixed* c; FT_Fixed* normalized = NULL; @@ -2713,10 +2687,31 @@ coords, num_coords * sizeof ( FT_Fixed ) ); - a = mmvar->axis + num_coords; c = blend->coords + num_coords; - for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ ) - *c = a->def; + + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt instance_index; + FT_Var_Named_Style* named_style; + FT_Fixed* n; + + + instance_index = (FT_UInt)face->root.face_index >> 16; + named_style = mmvar->namedstyle + instance_index - 1; + + n = named_style->coords + num_coords; + for ( i = num_coords; i < mmvar->num_axis; i++, n++, c++ ) + *c = *n; + } + else + { + FT_Var_Axis* a; + + + a = mmvar->axis + num_coords; + for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ ) + *c = a->def; + } if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 081fa2f1a..70df32b21 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -657,46 +657,17 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Int instance_index = face_index >> 16; + FT_UInt instance_index = (FT_UInt)face_index >> 16; if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && instance_index > 0 ) { - error = TT_Get_MM_Var( face, NULL ); + error = TT_Set_Named_Instance( face, instance_index ); if ( error ) goto Exit; - if ( face->blend->mmvar->namedstyle ) - { - FT_Memory memory = ttface->memory; - - FT_Var_Named_Style* named_style; - FT_String* style_name; - - - /* in `face_index', the instance index starts with value 1 */ - named_style = face->blend->mmvar->namedstyle + instance_index - 1; - error = sfnt->get_name( face, - (FT_UShort)named_style->strid, - &style_name ); - if ( error ) - goto Exit; - - /* set style name; if already set, replace it */ - if ( face->root.style_name ) - FT_FREE( face->root.style_name ); - face->root.style_name = style_name; - - /* finally, select the named instance */ - error = TT_Set_Var_Design( face, - face->blend->mmvar->num_axis, - named_style->coords ); - if ( error ) - goto Exit; - - tt_apply_mvar( face ); - } + tt_apply_mvar( face ); } }