From 9c45ac39661af69119e95d25e4d4dc09c6467d43 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 26 Oct 2016 16:00:00 +0200 Subject: [PATCH] Add `FT_Get_{MM,Var}_Blend_Coordinates' functions. * include/freetype/ftmm.h: Declare. * include/freetype/internal/services/svmm.h (FT_Get_MM_Blend_Func): New typedef. (MultiMasters): New MM service function `get_mm_blend'. (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. Update all callers. * src/base/ftmm.c (FT_Get_MM_Blend_Coordinates, FT_Get_Var_Blend_Coordinates): Implement. * src/truetype/ttdriver.c: Updated. * src/truetype/ttgxvar.c (TT_Get_MM_Blend): New function to handle `get_mm_blend' service. * src/truetype/ttgxvar.h: Updated. * src/type1/t1driver.c: Updated. * src/type1/t1load.c (T1_Get_MM_Blend): New function to handle `get_mm_blend' service. * src/type1/t1load.h: Updated. * docs/CHANGES: Document. --- ChangeLog | 29 +++++++++++ docs/CHANGES | 5 ++ include/freetype/ftmm.h | 46 ++++++++++++++++- include/freetype/internal/services/svmm.h | 60 ++++++++++++++--------- src/base/ftmm.c | 59 ++++++++++++++++++++++ src/truetype/ttdriver.c | 1 + src/truetype/ttgxvar.c | 58 ++++++++++++++++++++++ src/truetype/ttgxvar.h | 5 ++ src/type1/t1driver.c | 1 + src/type1/t1load.c | 35 +++++++++++++ src/type1/t1load.h | 5 ++ 11 files changed, 280 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1cd94bb52..54bc4e142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2016-10-26 Werner Lemberg + + Add `FT_Get_{MM,Var}_Blend_Coordinates' functions. + + * include/freetype/ftmm.h: Declare. + + * include/freetype/internal/services/svmm.h (FT_Get_MM_Blend_Func): + New typedef. + (MultiMasters): New MM service function `get_mm_blend'. + (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. + Update all callers. + + * src/base/ftmm.c (FT_Get_MM_Blend_Coordinates, + FT_Get_Var_Blend_Coordinates): Implement. + + * src/truetype/ttdriver.c: Updated. + + * src/truetype/ttgxvar.c (TT_Get_MM_Blend): New function to handle + `get_mm_blend' service. + * src/truetype/ttgxvar.h: Updated. + + * src/type1/t1driver.c: Updated. + + * src/type1/t1load.c (T1_Get_MM_Blend): New function to handle + `get_mm_blend' service. + * src/type1/t1load.h: Updated. + + * docs/CHANGES: Document. + 2016-10-26 Werner Lemberg * src/type1/t1load.c (parse_subrs): Fix limit check. diff --git a/docs/CHANGES b/docs/CHANGES index f0eddc53b..25e27400b 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -32,6 +32,11 @@ CHANGES BETWEEN 2.7 and 2.7.1 For example, you no longer get `Fixed' but rather `Sony Fixed' or `Misc Fixed Wide'. + - A new function `FT_Get_Var_Blend_Coordinates' (with its alias + name `FT_Get_MM_Blend_Coordinates') to retrieve the normalized + blend coordinates of the currently selected variation instance + has been added to the Multiple Masters interface. + ====================================================================== diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index b5d68589a..c05d3b61f 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -353,7 +353,8 @@ FT_BEGIN_HEADER /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0). */ + /* between 0 and 1.0 for MM fonts, and between -1.0 and */ + /* 1.0 for GX var fonts). */ /* */ /* */ /* FreeType error code. 0~means success. */ @@ -364,6 +365,35 @@ FT_BEGIN_HEADER FT_Fixed* coords ); + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_MM_Blend_Coordinates */ + /* */ + /* */ + /* For Multiple Masters and GX var fonts, get the normalized blend */ + /* coordinates of the currently selected interpolated font. */ + /* */ + /* */ + /* face :: A handle to the source face. */ + /* */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to 0.5 for MM fonts, and to 0 for GX var */ + /* fonts. */ + /* */ + /* coords :: The design coordinates array. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + /*************************************************************************/ /* */ /* */ @@ -377,6 +407,20 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_Var_Blend_Coordinates */ + /* */ + /* */ + /* This is another name of @FT_Get_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + /* */ diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h index b78a19f8e..809235807 100644 --- a/include/freetype/internal/services/svmm.h +++ b/include/freetype/internal/services/svmm.h @@ -58,12 +58,18 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Long* coords ); + typedef FT_Error + (*FT_Get_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + FT_DEFINE_SERVICE( MultiMasters ) { FT_Get_MM_Func get_mm; FT_Set_MM_Design_Func set_mm_design; FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Blend_Func get_mm_blend; FT_Get_MM_Var_Func get_mm_var; FT_Set_Var_Design_Func set_var_design; }; @@ -71,33 +77,41 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_PIC -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_ \ }; #else /* FT_CONFIG_OPTION_PIC */ -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_blend = get_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ } #endif /* FT_CONFIG_OPTION_PIC */ diff --git a/src/base/ftmm.c b/src/base/ftmm.c index 6b759ca46..138515e8f 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -231,4 +231,63 @@ } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + /* END */ diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index db8c63b01..1c4b617ee 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -470,6 +470,7 @@ (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 */ ) diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 11b290852..fd00ca45a 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -1183,6 +1183,64 @@ } + /*************************************************************************/ + /* */ + /* */ + /* TT_Get_MM_Blend */ + /* */ + /* */ + /* Get the blend (normalized) coordinates for this instance of the */ + /* font. */ + /* */ + /* */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, set the excess */ + /* values to 0. */ + /* */ + /* coords :: An array of `num_coords', each between [-1,1]. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_UInt i, nc; + + + if ( face->blend == NULL ) + { + if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) + return error; + } + + blend = face->blend; + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; ++i ) + coords[i] = blend->normalizedcoords[i]; + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + /*************************************************************************/ /* */ /* */ diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index aa8f6ea59..408de7100 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -148,6 +148,11 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + FT_LOCAL( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + FT_LOCAL( FT_Error ) TT_Set_Var_Design( TT_Face face, FT_UInt num_coords, diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index c8a87d585..e5fb70124 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -122,6 +122,7 @@ (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 */ }; diff --git a/src/type1/t1load.c b/src/type1/t1load.c index c573a469a..a785c6e44 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -412,6 +412,41 @@ } + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; ++i ) + coords[i] = axiscoords[i]; + for ( ; i < num_coords; i++ ) + coords[i] = 0x8000; + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, diff --git a/src/type1/t1load.h b/src/type1/t1load.h index b96fe5a74..1fbd0b4fd 100644 --- a/src/type1/t1load.h +++ b/src/type1/t1load.h @@ -79,6 +79,11 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + FT_LOCAL( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + FT_LOCAL( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords,