[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.
diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index cf40bc0..97773d4 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 02fdc53..e56afba 100644
--- a/src/psaux/pshints.h
+++ b/src/psaux/pshints.h
@@ -173,6 +173,16 @@
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 @@
*/
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 @@
/* 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 61fc8f8..538d589 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 );