summaryrefslogtreecommitdiff
path: root/freetype
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2018-11-14 22:29:24 +0000
committerChris Liddell <chris.liddell@artifex.com>2018-11-28 09:11:20 +0000
commitbfddf70400bb1fd4b3f7bfd72f333ad09a0b6cba (patch)
tree427e640f7e282844dee108a4101a3ccfa23710b1 /freetype
parent3f93e079aa448a202329fd08a350485c3504b9dd (diff)
downloadghostpdl-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.h81
-rw-r--r--freetype/include/freetype/internal/services/svmm.h104
-rw-r--r--freetype/src/base/ftmm.c59
-rw-r--r--freetype/src/cff/cffdrivr.c46
-rw-r--r--freetype/src/truetype/ttdriver.c24
-rw-r--r--freetype/src/type1/t1driver.c24
-rw-r--r--freetype/src/type1/t1load.c65
-rw-r--r--freetype/src/type1/t1load.h10
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 */