diff --git a/ChangeLog b/ChangeLog index 1bdfbe472..80e97b167 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2017-10-07 Werner Lemberg + + Make `FT_Set_Named_Instance' work. + + * src/cff/cffdrivr.c (cff_set_instance): New function. + (cff_service_multi_masters): Register it. + + * src/truetype/ttgxvar.c (TT_Set_Named_Instance): New function. + * src/truetype/ttgxvar.h: Updated. + * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Register + it. + + * src/type1/t1load.c (T1_Reset_MM_Blend): New function. + * src/type1/t1load.h: Updated. + * src/type1/t1driver.c (t1_service_multi_masters): Register it. + 2017-10-07 Werner Lemberg Make `FT_FACE_FLAG_VARIATION' work. diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 032ce3730..cf630a8a1 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -1109,6 +1109,17 @@ } + static FT_Error + cff_set_instance( CFF_Face face, + FT_UInt instance_index ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_instance( FT_FACE( face ), instance_index ); + } + + FT_DEFINE_SERVICE_MULTIMASTERSREC( cff_service_multi_masters, @@ -1119,7 +1130,7 @@ (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) NULL, /* set_instance */ + (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ (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/truetype/ttdriver.c b/src/truetype/ttdriver.c index af36481c1..ba05cefb3 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -498,7 +498,7 @@ (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) NULL, /* set_instance */ + (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ (FT_Done_Blend_Func) tt_done_blend /* done_blend */ diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index d2365ac3d..4ad6533bf 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2816,6 +2816,90 @@ } + /*************************************************************************/ + /* */ + /* */ + /* TT_Set_Named_Instance */ + /* */ + /* */ + /* Set the given named instance, also resetting any further */ + /* variation. */ + /* */ + /* */ + /* face :: A handle to the source face. */ + /* */ + /* instance_index :: The instance index, starting with value 1. */ + /* Value 0 indicates to not use an instance. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_Named_Instance( TT_Face face, + FT_UInt instance_index ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + GX_Blend blend; + FT_MM_Var* mmvar; + + FT_UInt num_instances; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + num_instances = (FT_UInt)face->root.style_flags >> 16; + + /* `instance_index' starts with value 1, thus `>' */ + if ( instance_index > num_instances ) + goto Exit; + + if ( instance_index > 0 && mmvar->namedstyle ) + { + FT_Memory memory = face->root.memory; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + named_style = mmvar->namedstyle + instance_index - 1; + + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set (or replace) 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, + mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + 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; + + Exit: + return error; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 7e81719a3..a9a116500 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -401,6 +401,10 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + FT_LOCAL( FT_Error ) + TT_Set_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 b319f566d..06cb26e47 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -126,7 +126,7 @@ (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) NULL, /* set_instance */ + (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ diff --git a/src/type1/t1load.c b/src/type1/t1load.c index 8ac3810ff..9259df64a 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -553,6 +553,18 @@ } + /* MM fonts don't have named instances, so only the design is reset */ + + FT_LOCAL_DEF( FT_Error ) + T1_Reset_MM_Blend( T1_Face face, + FT_UInt instance_index ) + { + FT_UNUSED( instance_index ); + + return T1_Set_MM_Blend( face, 0, NULL ); + } + + /*************************************************************************/ /* */ /* Just a wrapper around T1_Set_MM_Design to support the different */ diff --git a/src/type1/t1load.h b/src/type1/t1load.h index 2d86984f0..492ba5add 100644 --- a/src/type1/t1load.h +++ b/src/type1/t1load.h @@ -89,6 +89,10 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Long* coords ); + FT_LOCAL( FT_Error ) + T1_Reset_MM_Blend( T1_Face face, + FT_UInt instance_index ); + FT_LOCAL( FT_Error ) T1_Get_Var_Design( T1_Face face, FT_UInt num_coords,