From d718ac4ead0d711bd73d8103ba67cca10a55b3d9 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 11 Jan 2017 14:12:34 +0100 Subject: [PATCH] [truetype] Provide metrics variation service. * include/freetype/internal/services/svmetric.h (FT_Metrics_Adjust_Func): Reduce number of necessary parameters. * src/truetype/ttgxvar.c: Include FT_LIST_H. (tt_size_reset_iterator): New auxiliary function for... (tt_apply_var): New function. * src/truetype/ttgxvar.h: Updated. * src/truetype/ttdriver.c (tt_service_metrics_variations): Add `tt_apply_mvar'. * include/freetype/internal/ftserv.h (FT_ServiceCache): Add metrics variation service. --- ChangeLog | 19 ++++ include/freetype/internal/ftserv.h | 1 + include/freetype/internal/services/svmetric.h | 6 +- src/truetype/ttdriver.c | 2 +- src/truetype/ttgxvar.c | 97 +++++++++++++++++++ src/truetype/ttgxvar.h | 3 + 6 files changed, 123 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3bb28bb7..b196b5a57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2017-01-11 Werner Lemberg + + [truetype] Provide metrics variation service. + + * include/freetype/internal/services/svmetric.h + (FT_Metrics_Adjust_Func): Reduce number of necessary parameters. + + * src/truetype/ttgxvar.c: Include FT_LIST_H. + (tt_size_reset_iterator): New auxiliary function for... + (tt_apply_var): New function. + + * src/truetype/ttgxvar.h: Updated. + + * src/truetype/ttdriver.c (tt_service_metrics_variations): Add + `tt_apply_mvar'. + + * include/freetype/internal/ftserv.h (FT_ServiceCache): Add metrics + variation service. + 2017-01-11 Werner Lemberg [truetype] Parse `MVAR' table. diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h index ad71cb658..c84afba4a 100644 --- a/include/freetype/internal/ftserv.h +++ b/include/freetype/internal/ftserv.h @@ -714,6 +714,7 @@ FT_BEGIN_HEADER { FT_Pointer service_POSTSCRIPT_FONT_NAME; FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_METRICS_VARIATIONS; FT_Pointer service_GLYPH_DICT; FT_Pointer service_PFR_METRICS; FT_Pointer service_WINFNT; diff --git a/include/freetype/internal/services/svmetric.h b/include/freetype/internal/services/svmetric.h index 8f2fb60d0..cac9bf88b 100644 --- a/include/freetype/internal/services/svmetric.h +++ b/include/freetype/internal/services/svmetric.h @@ -74,10 +74,8 @@ FT_BEGIN_HEADER /* MVAR */ - typedef FT_Error - (*FT_Metrics_Adjust_Func)( FT_Face face, - FT_ULong tag, - FT_Int *avalue ); + typedef void + (*FT_Metrics_Adjust_Func)( FT_Face face ); FT_DEFINE_SERVICE( MetricsVariations ) diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 3cbff5956..19f7858b3 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -507,7 +507,7 @@ (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ - (FT_Metrics_Adjust_Func) NULL /* metrics_adjust */ + (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ ) #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index c89a1c971..03803351a 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -50,6 +50,7 @@ #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_TAGS_H #include FT_MULTIPLE_MASTERS_H +#include FT_LIST_H #include "ttpload.h" #include "ttgxvar.h" @@ -1175,6 +1176,102 @@ } + static FT_Error + tt_size_reset_iterator( FT_ListNode node, + void* user ) + { + TT_Size size = (TT_Size)node->data; + + FT_UNUSED( user ); + + + tt_size_reset( size, 1 ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_apply_mvar */ + /* */ + /* */ + /* Apply `MVAR' table adjustments. */ + /* */ + /* */ + /* face :: The font face. */ + /* */ + FT_LOCAL_DEF( void ) + tt_apply_mvar( TT_Face face ) + { + GX_Blend blend = face->blend; + GX_Value value, limit; + + + if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) + return; + + value = blend->mvar_table->values; + limit = value + blend->mvar_table->valueCount; + + for ( ; value < limit; value++ ) + { + FT_Short* p = ft_var_get_value_pointer( face, value->tag ); + FT_Int delta; + + + delta = ft_var_get_item_delta( face, + &blend->mvar_table->itemStore, + value->outerIndex, + value->innerIndex ); + + FT_TRACE5(( "value %c%c%c%c (%d units) adjusted by %d units (MVAR)\n", + (FT_Char)( value->tag >> 24 ), + (FT_Char)( value->tag >> 16 ), + (FT_Char)( value->tag >> 8 ), + (FT_Char)( value->tag ), + value->unmodified, + delta )); + + /* since we handle both signed and unsigned values as FT_Short, */ + /* ensure proper overflow arithmetic */ + *p = (FT_Short)( value->unmodified + (FT_Short)delta ); + } + + /* adjust all derived values */ + { + FT_Face root = &face->root; + + + if ( face->os2.version != 0xFFFFU ) + { + if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) + { + root->ascender = face->os2.sTypoAscender; + root->descender = face->os2.sTypoDescender; + + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; + } + else + { + root->ascender = (FT_Short)face->os2.usWinAscent; + root->descender = -(FT_Short)face->os2.usWinDescent; + + root->height = root->ascender - root->descender; + } + } + + /* iterate over all FT_Size objects and call `tt_size_reset' */ + /* to propagate the metrics changes */ + FT_List_Iterate( &root->sizes_list, + tt_size_reset_iterator, + NULL ); + } + } + + typedef struct GX_GVar_Head_ { FT_Long version; diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index a04b410d8..bbe240f91 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -332,6 +332,9 @@ FT_BEGIN_HEADER FT_UInt gindex, FT_Int *adelta ); + FT_LOCAL( void ) + tt_apply_mvar( TT_Face face ); + FT_LOCAL( FT_Error ) tt_get_var_blend( TT_Face face, FT_UInt *num_coords,