[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.
<cntrmask, hintmask>: Ignore if not hinting.
Update references.
This commit is contained in:
Ewald Hew 2017-08-21 14:20:47 +08:00
parent 423d7cf165
commit c48e55b738
3 changed files with 89 additions and 54 deletions

View File

@ -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,
&params.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,
&params.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,
&params.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 );

View File

@ -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,

View File

@ -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 );