diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2018-11-14 22:29:24 +0000 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2018-11-28 09:11:20 +0000 |
commit | bfddf70400bb1fd4b3f7bfd72f333ad09a0b6cba (patch) | |
tree | 427e640f7e282844dee108a4101a3ccfa23710b1 /freetype | |
parent | 3f93e079aa448a202329fd08a350485c3504b9dd (diff) | |
download | ghostpdl-bfddf70400bb1fd4b3f7bfd72f333ad09a0b6cba.tar.gz |
Add a setweightvector analogue in Freetype
Avoids the need to recreate the FT font everytime the weightvector changes.
These Freetype changes have been accepted upstream:
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=78a1e69517ca067224d6e33beffd25e2ec8361d2
Diffstat (limited to 'freetype')
-rw-r--r-- | freetype/include/freetype/ftmm.h | 81 | ||||
-rw-r--r-- | freetype/include/freetype/internal/services/svmm.h | 104 | ||||
-rw-r--r-- | freetype/src/base/ftmm.c | 59 | ||||
-rw-r--r-- | freetype/src/cff/cffdrivr.c | 46 | ||||
-rw-r--r-- | freetype/src/truetype/ttdriver.c | 24 | ||||
-rw-r--r-- | freetype/src/type1/t1driver.c | 24 | ||||
-rw-r--r-- | freetype/src/type1/t1load.c | 65 | ||||
-rw-r--r-- | freetype/src/type1/t1load.h | 10 |
8 files changed, 339 insertions, 74 deletions
diff --git a/freetype/include/freetype/ftmm.h b/freetype/include/freetype/ftmm.h index 9948102c1..8be85ef07 100644 --- a/freetype/include/freetype/ftmm.h +++ b/freetype/include/freetype/ftmm.h @@ -527,6 +527,87 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ + /* FT_Set_MM_WeightVector */ + /* */ + /* <Description> */ + /* For Adobe MM fonts, choose an interpolated font design by */ + /* directly setting the weight vector. */ + /* */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* len :: The length of the weight vector array. If it is */ + /* larger than the number of designs, the extra */ + /* values are ignored. If it is less than the number */ + /* of designs, the remaining values are set to zero. */ + /* */ + /* weightvector :: An array representing the weight vector. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Adobe Multiple Master fonts limit the number of designs, and */ + /* thus the length of the WeightVector to 16. */ + /* */ + /* If len is zero and weightvector is NULL, the WeightVector is */ + /* reset to the default values. */ + /* The Adobe documentation also states that the values in the */ + /* WeightVector must total 1.0 +/- 0.001. In practice this does */ + /* not seem to be enforced, so is not enforced, here either. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_WeightVector( FT_Face face, + FT_UInt len, + FT_Fixed* weightvector ); + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_WeightVector */ + /* */ + /* <Description> */ + /* For Adobe MM fonts, retrieve the current weight vector of the font */ + /* */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <InOut> */ + /* len :: Pointer to the size of the array to be filled. If */ + /* size of the array less than the number of designs, */ + /* an Invalid_Argument is returned, and len is set to */ + /* the required size (the number of designs). If the */ + /* size of the array is greater than the number of */ + /* designs, the remaining entries are set to 0. On */ + /* successful completion, len is set to the number of */ + /* designs (i.e. the number of values written to the */ + /* array. */ + /* */ + /* <Output> */ + /* weightvector :: An array to be filled. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Adobe Multiple Master fonts limit the number of designs, and */ + /* thus the length of the WeightVector to 16. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_WeightVector( FT_Face face, + FT_UInt* len, + FT_Fixed* weightvector ); + + /*************************************************************************/ + /* */ + /* <Function> */ /* FT_Get_Var_Blend_Coordinates */ /* */ /* <Description> */ diff --git a/freetype/include/freetype/internal/services/svmm.h b/freetype/include/freetype/internal/services/svmm.h index bcbb38e2c..882862e01 100644 --- a/freetype/include/freetype/internal/services/svmm.h +++ b/freetype/include/freetype/internal/services/svmm.h @@ -86,17 +86,31 @@ FT_BEGIN_HEADER typedef void (*FT_Done_Blend_Func)( FT_Face ); + /* use return value -1 to indicate that the new coordinates */ + /* are equal to the current ones; no changes are thus needed */ + typedef FT_Error + (*FT_Set_MM_WeightVector_Func)( FT_Face face, + FT_UInt len, + FT_Fixed* weight_vector ); + + typedef FT_Error + (*FT_Get_MM_WeightVector_Func)( FT_Face face, + FT_UInt* len, + FT_Fixed* weight_vector ); + 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; - FT_Get_Var_Design_Func get_var_design; - FT_Set_Instance_Func set_instance; + 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; + FT_Get_Var_Design_Func get_var_design; + FT_Set_Instance_Func set_instance; + FT_Set_MM_WeightVector_Func set_mm_weightvector; + FT_Get_MM_WeightVector_Func get_mm_weightvector; /* for internal use; only needed for code sharing between modules */ FT_Get_Var_Blend_Func get_var_blend; @@ -106,29 +120,33 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_PIC -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - get_var_blend_, \ - done_blend_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - get_var_blend_, \ - done_blend_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + set_weightvector_,\ + get_weightvector_,\ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + set_weightvector_, \ + get_weightvector_, \ + get_var_blend_, \ + done_blend_ \ }; #else /* FT_CONFIG_OPTION_PIC */ @@ -142,21 +160,25 @@ FT_BEGIN_HEADER set_var_design_, \ get_var_design_, \ set_instance_, \ + set_weightvector, \ + get_weightvector, \ get_var_blend_, \ done_blend_ ) \ 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_; \ - clazz->get_var_design = get_var_design_; \ - clazz->set_instance = set_instance_; \ - clazz->get_var_blend = get_var_blend_; \ - clazz->done_blend = done_blend_; \ + 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_; \ + clazz->get_var_design = get_var_design_; \ + clazz->set_instance = set_instance_; \ + clazz->set_weightvector = set_weightvector; \ + clazz->get_weightvector = get_weightvector; \ + clazz->get_var_blend = get_var_blend_; \ + clazz->done_blend = done_blend_; \ } #endif /* FT_CONFIG_OPTION_PIC */ diff --git a/freetype/src/base/ftmm.c b/freetype/src/base/ftmm.c index 800441bca..8e841c070 100644 --- a/freetype/src/base/ftmm.c +++ b/freetype/src/base/ftmm.c @@ -198,6 +198,65 @@ return error; } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_WeightVector( FT_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( len && !weightvector ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_mm_weightvector ) + error = service->set_mm_weightvector( face, len, weightvector ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_WeightVector( FT_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( len && !weightvector ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_weightvector ) + error = service->get_mm_weightvector( face, len, weightvector ); + } + + return error; + } + /* documentation is in ftmm.h */ diff --git a/freetype/src/cff/cffdrivr.c b/freetype/src/cff/cffdrivr.c index df896848d..06e2d743d 100644 --- a/freetype/src/cff/cffdrivr.c +++ b/freetype/src/cff/cffdrivr.c @@ -859,6 +859,28 @@ return mm->get_mm_blend( FT_FACE( face ), num_coords, coords ); } + static FT_Error + cff_set_mm_weightvector( CFF_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector ); + } + + + static FT_Error + cff_get_mm_weightvector( CFF_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector ); + } static FT_Error cff_get_mm_var( CFF_Face face, @@ -909,17 +931,19 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( cff_service_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ - (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) 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 */ + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (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) cff_set_instance, /* set_instance */ + (FT_Set_MM_WeightVector_Func) cff_set_mm_weightvector,/* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func) cff_get_mm_weightvector,/* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ ) diff --git a/freetype/src/truetype/ttdriver.c b/freetype/src/truetype/ttdriver.c index 820cafbb8..88b499ce0 100644 --- a/freetype/src/truetype/ttdriver.c +++ b/freetype/src/truetype/ttdriver.c @@ -491,17 +491,19 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (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 */ - (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ - (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 */ + (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 */ + (FT_Get_Var_Design_Func) TT_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) TT_Set_Named_Instance,/* set_instance */ + (FT_Set_MM_WeightVector_Func) NULL, /* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func) NULL, /* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ ) FT_DEFINE_SERVICE_METRICSVARIATIONSREC( diff --git a/freetype/src/type1/t1driver.c b/freetype/src/type1/t1driver.c index 029b410b4..8fcb2a385 100644 --- a/freetype/src/type1/t1driver.c +++ b/freetype/src/type1/t1driver.c @@ -122,17 +122,19 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (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 */ - (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ - (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 */ + (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 */ + (FT_Get_Var_Design_Func) T1_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ + (FT_Set_MM_WeightVector_Func) T1_Set_MM_WeightVector, /* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func) T1_Get_MM_WeightVector, /* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif diff --git a/freetype/src/type1/t1load.c b/freetype/src/type1/t1load.c index 9dfa637a6..94e856058 100644 --- a/freetype/src/type1/t1load.c +++ b/freetype/src/type1/t1load.c @@ -475,6 +475,71 @@ return FT_Err_Ok; } + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_WeightVector( T1_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + PS_Blend blend = face->blend; + FT_UInt i, n; + + if ( !blend) + return FT_THROW( Invalid_Argument ); + + if ( len == 0 && weightvector == NULL ) + { + for ( i = 0; i < blend->num_designs; i++ ) + blend->weight_vector[i] = blend->default_weight_vector[i]; + } + else + { + if ( weightvector == NULL ) + return FT_THROW( Invalid_Argument ); + + n = len < blend->num_designs ? len : blend->num_designs; + + for ( i = 0; i < n; i++ ) + blend->weight_vector[i] = weightvector[i]; + + 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; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_WeightVector( T1_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + PS_Blend blend = face->blend; + FT_UInt i; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + if (*len < blend->num_designs) + { + *len = blend->num_designs; + return FT_THROW( Invalid_Argument ); + } + + for (i = 0; i < blend->num_designs; i++) + weightvector[i] = blend->weight_vector[i]; + for (; i < *len; i++) + weightvector[i] = (FT_Fixed)0; + + *len = blend->num_designs; + + return FT_Err_Ok; + } + FT_LOCAL_DEF( FT_Error ) T1_Set_MM_Design( T1_Face face, diff --git a/freetype/src/type1/t1load.h b/freetype/src/type1/t1load.h index 03be3f7f9..5763ccc1e 100644 --- a/freetype/src/type1/t1load.h +++ b/freetype/src/type1/t1load.h @@ -106,6 +106,16 @@ FT_BEGIN_HEADER FT_LOCAL( void ) T1_Done_Blend( T1_Face face ); + FT_LOCAL( FT_Error ) + T1_Set_MM_WeightVector( T1_Face face, + FT_UInt len, + FT_Fixed* weightvector ); + + FT_LOCAL( FT_Error ) + T1_Get_MM_WeightVector( T1_Face face, + FT_UInt* len, + FT_Fixed* weightvector ); + #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ |