From c48e55b738b5a3cc57f20eb7b949fcfec5ca9dd4 Mon Sep 17 00:00:00 2001 From: Ewald Hew Date: Mon, 21 Aug 2017 14:20:47 +0800 Subject: [PATCH] [psaux] Performance improvements (#43248). Implement proper disabling of hinting procedures when not hinting. This results in a ~30% speedup. * src/psaux/pshints.h (CF2_HintData): Gather hintmaps into hinting context. * src/psaux/pshints.c: Do not allocate structs unless needed. Skip hintmap funcs calls. Update references. * src/psaux/psintrp.c (cf2_interpT2CharString): Initialization for hinting context. : Ignore if not hinting. Update references. --- src/psaux/pshints.c | 111 ++++++++++++++++++++++++++------------------ src/psaux/pshints.h | 21 ++++++--- src/psaux/psintrp.c | 11 +++-- 3 files changed, 89 insertions(+), 54 deletions(-) diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c index cf40bc01a..97773d4a5 100644 --- a/src/psaux/pshints.c +++ b/src/psaux/pshints.c @@ -814,6 +814,9 @@ FT_Byte maskByte; + if ( !hintmap ) + return; + /* check whether initial map is constructed */ if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) ) { @@ -1072,6 +1075,7 @@ /* CF2_Fixed hShift, */ CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, + CF2_HintData hintData, CF2_HintMask hintMask, CF2_Fixed hintOriginY, const CF2_Blues blues, @@ -1082,26 +1086,34 @@ glyphpath->font = font; glyphpath->callbacks = callbacks; - cf2_arrstack_init( &glyphpath->hintMoves, - font->memory, - &font->error, - sizeof ( CF2_HintMoveRec ) ); + if ( font->hinted ) + { + cf2_arrstack_init( &hintData->hintMoves, + font->memory, + &font->error, + sizeof ( CF2_HintMoveRec ) ); - cf2_hintmap_init( &glyphpath->initialHintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); - cf2_hintmap_init( &glyphpath->firstHintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); - cf2_hintmap_init( &glyphpath->hintMap, - font, - &glyphpath->initialHintMap, - &glyphpath->hintMoves, - scaleY ); + cf2_hintmap_init( &hintData->initialHintMap, + font, + &hintData->initialHintMap, + &hintData->hintMoves, + scaleY ); + cf2_hintmap_init( &hintData->firstHintMap, + font, + &hintData->initialHintMap, + &hintData->hintMoves, + scaleY ); + cf2_hintmap_init( &hintData->hintMap, + font, + &hintData->initialHintMap, + &hintData->hintMoves, + scaleY ); + + glyphpath->hintMap = &hintData->hintMap; + glyphpath->firstHintMap = &hintData->firstHintMap; + glyphpath->initialHintMap = &hintData->initialHintMap; + glyphpath->hintMoves = &hintData->hintMoves; + } glyphpath->scaleX = font->innerTransform.a; glyphpath->scaleC = font->innerTransform.c; @@ -1138,7 +1150,8 @@ FT_LOCAL_DEF( void ) cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ) { - cf2_arrstack_finalize( &glyphpath->hintMoves ); + if ( glyphpath->font->hinted ) + cf2_arrstack_finalize( glyphpath->hintMoves ); } @@ -1160,7 +1173,9 @@ pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ), FT_MulFix( glyphpath->scaleC, y ) ); - pt.y = cf2_hintmap_map( hintmap, y ); + pt.y = hintmap ? cf2_hintmap_map( hintmap, y ) + : FT_MulFix( glyphpath->scaleY, y ); + ppt->x = ADD_INT32( FT_MulFix( glyphpath->font->outerTransform.a, pt.x ), @@ -1366,7 +1381,7 @@ { /* use first hint map if closing */ cf2_glyphpath_hintPoint( glyphpath, - &glyphpath->firstHintMap, + glyphpath->firstHintMap, ¶ms.pt1, glyphpath->prevElemP1.x, glyphpath->prevElemP1.y ); @@ -1428,7 +1443,7 @@ /* if we are closing the subpath, then nextP0 is in the first */ /* hint zone */ cf2_glyphpath_hintPoint( glyphpath, - &glyphpath->firstHintMap, + glyphpath->firstHintMap, ¶ms.pt1, nextP0->x, nextP0->y ); @@ -1478,7 +1493,8 @@ /* Test if move has really happened yet; it would have called */ /* `cf2_hintmap_build' to set `isValid'. */ - if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ) + if ( glyphpath->font->hinted && + !cf2_hintmap_isValid( glyphpath->hintMap ) ) { /* we are here iff first subpath is missing a moveto operator: */ /* synthesize first moveTo to finish initialization of hintMap */ @@ -1488,7 +1504,7 @@ } cf2_glyphpath_hintPoint( glyphpath, - &glyphpath->hintMap, + glyphpath->hintMap, ¶ms.pt1, start.x, start.y ); @@ -1677,18 +1693,21 @@ glyphpath->moveIsPending = TRUE; - /* ensure we have a valid map with current mask */ - if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) || - cf2_hintmask_isNew( glyphpath->hintMask ) ) - cf2_hintmap_build( &glyphpath->hintMap, - glyphpath->hStemHintArray, - glyphpath->vStemHintArray, - glyphpath->hintMask, - glyphpath->hintOriginY, - FALSE ); + /* ensure we have a valid map with current mask, if hinting is on */ + if ( glyphpath->font->hinted ) + { + if ( !cf2_hintmap_isValid( glyphpath->hintMap ) || + cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); - /* save a copy of current HintMap to use when drawing initial point */ - glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */ + /* save a copy of current HintMap to use when drawing initial point */ + *glyphpath->firstHintMap = *glyphpath->hintMap; /* structure copy */ + } } @@ -1768,11 +1787,12 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || - glyphpath->hintMap.count == 0 ); + FT_ASSERT( !glyphpath->font->hinted || + cf2_hintmap_isValid( glyphpath->hintMap ) || + glyphpath->hintMap->count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->hintMap, + glyphpath->hintMap, &P0, P1, FALSE ); @@ -1786,7 +1806,7 @@ /* update current map */ if ( newHintMap ) - cf2_hintmap_build( &glyphpath->hintMap, + cf2_hintmap_build( glyphpath->hintMap, glyphpath->hStemHintArray, glyphpath->vStemHintArray, glyphpath->hintMask, @@ -1856,11 +1876,12 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || - glyphpath->hintMap.count == 0 ); + FT_ASSERT( !glyphpath->font->hinted || + cf2_hintmap_isValid( glyphpath->hintMap ) || + glyphpath->hintMap->count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->hintMap, + glyphpath->hintMap, &P0, P1, FALSE ); @@ -1876,7 +1897,7 @@ /* update current map */ if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) - cf2_hintmap_build( &glyphpath->hintMap, + cf2_hintmap_build( glyphpath->hintMap, glyphpath->hStemHintArray, glyphpath->vStemHintArray, glyphpath->hintMask, @@ -1907,7 +1928,7 @@ /* empty the final element from the queue and close the path */ if ( glyphpath->elemIsQueued ) cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->hintMap, + glyphpath->hintMap, &glyphpath->offsetStart0, glyphpath->offsetStart1, TRUE ); diff --git a/src/psaux/pshints.h b/src/psaux/pshints.h index 02fdc53cb..e56afbabe 100644 --- a/src/psaux/pshints.h +++ b/src/psaux/pshints.h @@ -173,6 +173,16 @@ FT_BEGIN_HEADER FT_Bool initialMap ); + typedef struct CF2_HintDataRec_ + { + CF2_HintMapRec hintMap; /* current hint map */ + CF2_HintMapRec firstHintMap; /* saved copy */ + CF2_HintMapRec initialHintMap; /* based on all captured hints */ + + CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */ + + } CF2_HintDataRec, *CF2_HintData; + /* * GlyphPath is a wrapper for drawing operations that scales the * coordinates according to the render matrix and HintMap. It also tracks @@ -181,17 +191,15 @@ FT_BEGIN_HEADER */ typedef struct CF2_GlyphPathRec_ { - /* TODO: gather some of these into a hinting context */ - CF2_Font font; /* font instance */ CF2_OutlineCallbacks callbacks; /* outline consumer */ - CF2_HintMapRec hintMap; /* current hint map */ - CF2_HintMapRec firstHintMap; /* saved copy */ - CF2_HintMapRec initialHintMap; /* based on all captured hints */ + CF2_HintMap hintMap; /* ptr to current hint map */ + CF2_HintMap firstHintMap; /* ptr to saved copy */ + CF2_HintMap initialHintMap; /* based on all captured hints */ - CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */ + CF2_ArrStack hintMoves; /* list of hint moves for 2nd pass */ CF2_Fixed scaleX; /* matrix a */ CF2_Fixed scaleC; /* matrix c */ @@ -253,6 +261,7 @@ FT_BEGIN_HEADER /* CF2_Fixed hShift, */ CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, + CF2_HintData hintData, CF2_HintMask hintMask, CF2_Fixed hintOrigin, const CF2_Blues blues, diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c index 61fc8f856..538d5895d 100644 --- a/src/psaux/psintrp.c +++ b/src/psaux/psintrp.c @@ -524,9 +524,9 @@ CF2_ArrStackRec vStemHintArray; CF2_HintMaskRec hintMask; + CF2_HintDataRec hintData; CF2_GlyphPathRec glyphPath; - FT_ZERO( &storage ); FT_ZERO( &results ); FT_ZERO( &flexStore ); @@ -560,6 +560,7 @@ /* hShift, */ &hStemHintArray, &vStemHintArray, + &hintData, &hintMask, hintOriginY, &font->blues, @@ -2504,6 +2505,10 @@ /* `cf2_hintmask_read' (which also traces the mask bytes) */ FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); + /* disregard if not hinting */ + if ( !font->hinted ) + break; + /* never add hints after the mask is computed */ if ( cf2_stack_count( opStack ) > 1 && cf2_hintmask_isValid( &hintMask ) ) @@ -2553,8 +2558,8 @@ cf2_hintmap_init( &counterHintMap, font, - &glyphPath.initialHintMap, - &glyphPath.hintMoves, + glyphPath.initialHintMap, + glyphPath.hintMoves, scaleY ); cf2_hintmask_init( &counterMask, error );