[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:
parent
423d7cf165
commit
c48e55b738
|
@ -814,6 +814,9 @@
|
||||||
FT_Byte maskByte;
|
FT_Byte maskByte;
|
||||||
|
|
||||||
|
|
||||||
|
if ( !hintmap )
|
||||||
|
return;
|
||||||
|
|
||||||
/* check whether initial map is constructed */
|
/* check whether initial map is constructed */
|
||||||
if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) )
|
if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) )
|
||||||
{
|
{
|
||||||
|
@ -1072,6 +1075,7 @@
|
||||||
/* CF2_Fixed hShift, */
|
/* CF2_Fixed hShift, */
|
||||||
CF2_ArrStack hStemHintArray,
|
CF2_ArrStack hStemHintArray,
|
||||||
CF2_ArrStack vStemHintArray,
|
CF2_ArrStack vStemHintArray,
|
||||||
|
CF2_HintData hintData,
|
||||||
CF2_HintMask hintMask,
|
CF2_HintMask hintMask,
|
||||||
CF2_Fixed hintOriginY,
|
CF2_Fixed hintOriginY,
|
||||||
const CF2_Blues blues,
|
const CF2_Blues blues,
|
||||||
|
@ -1082,26 +1086,34 @@
|
||||||
glyphpath->font = font;
|
glyphpath->font = font;
|
||||||
glyphpath->callbacks = callbacks;
|
glyphpath->callbacks = callbacks;
|
||||||
|
|
||||||
cf2_arrstack_init( &glyphpath->hintMoves,
|
if ( font->hinted )
|
||||||
font->memory,
|
{
|
||||||
&font->error,
|
cf2_arrstack_init( &hintData->hintMoves,
|
||||||
sizeof ( CF2_HintMoveRec ) );
|
font->memory,
|
||||||
|
&font->error,
|
||||||
|
sizeof ( CF2_HintMoveRec ) );
|
||||||
|
|
||||||
cf2_hintmap_init( &glyphpath->initialHintMap,
|
cf2_hintmap_init( &hintData->initialHintMap,
|
||||||
font,
|
font,
|
||||||
&glyphpath->initialHintMap,
|
&hintData->initialHintMap,
|
||||||
&glyphpath->hintMoves,
|
&hintData->hintMoves,
|
||||||
scaleY );
|
scaleY );
|
||||||
cf2_hintmap_init( &glyphpath->firstHintMap,
|
cf2_hintmap_init( &hintData->firstHintMap,
|
||||||
font,
|
font,
|
||||||
&glyphpath->initialHintMap,
|
&hintData->initialHintMap,
|
||||||
&glyphpath->hintMoves,
|
&hintData->hintMoves,
|
||||||
scaleY );
|
scaleY );
|
||||||
cf2_hintmap_init( &glyphpath->hintMap,
|
cf2_hintmap_init( &hintData->hintMap,
|
||||||
font,
|
font,
|
||||||
&glyphpath->initialHintMap,
|
&hintData->initialHintMap,
|
||||||
&glyphpath->hintMoves,
|
&hintData->hintMoves,
|
||||||
scaleY );
|
scaleY );
|
||||||
|
|
||||||
|
glyphpath->hintMap = &hintData->hintMap;
|
||||||
|
glyphpath->firstHintMap = &hintData->firstHintMap;
|
||||||
|
glyphpath->initialHintMap = &hintData->initialHintMap;
|
||||||
|
glyphpath->hintMoves = &hintData->hintMoves;
|
||||||
|
}
|
||||||
|
|
||||||
glyphpath->scaleX = font->innerTransform.a;
|
glyphpath->scaleX = font->innerTransform.a;
|
||||||
glyphpath->scaleC = font->innerTransform.c;
|
glyphpath->scaleC = font->innerTransform.c;
|
||||||
|
@ -1138,7 +1150,8 @@
|
||||||
FT_LOCAL_DEF( void )
|
FT_LOCAL_DEF( void )
|
||||||
cf2_glyphpath_finalize( CF2_GlyphPath glyphpath )
|
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 ),
|
pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ),
|
||||||
FT_MulFix( glyphpath->scaleC, y ) );
|
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(
|
ppt->x = ADD_INT32(
|
||||||
FT_MulFix( glyphpath->font->outerTransform.a, pt.x ),
|
FT_MulFix( glyphpath->font->outerTransform.a, pt.x ),
|
||||||
|
@ -1366,7 +1381,7 @@
|
||||||
{
|
{
|
||||||
/* use first hint map if closing */
|
/* use first hint map if closing */
|
||||||
cf2_glyphpath_hintPoint( glyphpath,
|
cf2_glyphpath_hintPoint( glyphpath,
|
||||||
&glyphpath->firstHintMap,
|
glyphpath->firstHintMap,
|
||||||
¶ms.pt1,
|
¶ms.pt1,
|
||||||
glyphpath->prevElemP1.x,
|
glyphpath->prevElemP1.x,
|
||||||
glyphpath->prevElemP1.y );
|
glyphpath->prevElemP1.y );
|
||||||
|
@ -1428,7 +1443,7 @@
|
||||||
/* if we are closing the subpath, then nextP0 is in the first */
|
/* if we are closing the subpath, then nextP0 is in the first */
|
||||||
/* hint zone */
|
/* hint zone */
|
||||||
cf2_glyphpath_hintPoint( glyphpath,
|
cf2_glyphpath_hintPoint( glyphpath,
|
||||||
&glyphpath->firstHintMap,
|
glyphpath->firstHintMap,
|
||||||
¶ms.pt1,
|
¶ms.pt1,
|
||||||
nextP0->x,
|
nextP0->x,
|
||||||
nextP0->y );
|
nextP0->y );
|
||||||
|
@ -1478,7 +1493,8 @@
|
||||||
|
|
||||||
/* Test if move has really happened yet; it would have called */
|
/* Test if move has really happened yet; it would have called */
|
||||||
/* `cf2_hintmap_build' to set `isValid'. */
|
/* `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: */
|
/* we are here iff first subpath is missing a moveto operator: */
|
||||||
/* synthesize first moveTo to finish initialization of hintMap */
|
/* synthesize first moveTo to finish initialization of hintMap */
|
||||||
|
@ -1488,7 +1504,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
cf2_glyphpath_hintPoint( glyphpath,
|
cf2_glyphpath_hintPoint( glyphpath,
|
||||||
&glyphpath->hintMap,
|
glyphpath->hintMap,
|
||||||
¶ms.pt1,
|
¶ms.pt1,
|
||||||
start.x,
|
start.x,
|
||||||
start.y );
|
start.y );
|
||||||
|
@ -1677,18 +1693,21 @@
|
||||||
|
|
||||||
glyphpath->moveIsPending = TRUE;
|
glyphpath->moveIsPending = TRUE;
|
||||||
|
|
||||||
/* ensure we have a valid map with current mask */
|
/* ensure we have a valid map with current mask, if hinting is on */
|
||||||
if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ||
|
if ( glyphpath->font->hinted )
|
||||||
cf2_hintmask_isNew( glyphpath->hintMask ) )
|
{
|
||||||
cf2_hintmap_build( &glyphpath->hintMap,
|
if ( !cf2_hintmap_isValid( glyphpath->hintMap ) ||
|
||||||
glyphpath->hStemHintArray,
|
cf2_hintmask_isNew( glyphpath->hintMask ) )
|
||||||
glyphpath->vStemHintArray,
|
cf2_hintmap_build( glyphpath->hintMap,
|
||||||
glyphpath->hintMask,
|
glyphpath->hStemHintArray,
|
||||||
glyphpath->hintOriginY,
|
glyphpath->vStemHintArray,
|
||||||
FALSE );
|
glyphpath->hintMask,
|
||||||
|
glyphpath->hintOriginY,
|
||||||
|
FALSE );
|
||||||
|
|
||||||
/* save a copy of current HintMap to use when drawing initial point */
|
/* save a copy of current HintMap to use when drawing initial point */
|
||||||
glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */
|
*glyphpath->firstHintMap = *glyphpath->hintMap; /* structure copy */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1768,11 +1787,12 @@
|
||||||
|
|
||||||
if ( glyphpath->elemIsQueued )
|
if ( glyphpath->elemIsQueued )
|
||||||
{
|
{
|
||||||
FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
|
FT_ASSERT( !glyphpath->font->hinted ||
|
||||||
glyphpath->hintMap.count == 0 );
|
cf2_hintmap_isValid( glyphpath->hintMap ) ||
|
||||||
|
glyphpath->hintMap->count == 0 );
|
||||||
|
|
||||||
cf2_glyphpath_pushPrevElem( glyphpath,
|
cf2_glyphpath_pushPrevElem( glyphpath,
|
||||||
&glyphpath->hintMap,
|
glyphpath->hintMap,
|
||||||
&P0,
|
&P0,
|
||||||
P1,
|
P1,
|
||||||
FALSE );
|
FALSE );
|
||||||
|
@ -1786,7 +1806,7 @@
|
||||||
|
|
||||||
/* update current map */
|
/* update current map */
|
||||||
if ( newHintMap )
|
if ( newHintMap )
|
||||||
cf2_hintmap_build( &glyphpath->hintMap,
|
cf2_hintmap_build( glyphpath->hintMap,
|
||||||
glyphpath->hStemHintArray,
|
glyphpath->hStemHintArray,
|
||||||
glyphpath->vStemHintArray,
|
glyphpath->vStemHintArray,
|
||||||
glyphpath->hintMask,
|
glyphpath->hintMask,
|
||||||
|
@ -1856,11 +1876,12 @@
|
||||||
|
|
||||||
if ( glyphpath->elemIsQueued )
|
if ( glyphpath->elemIsQueued )
|
||||||
{
|
{
|
||||||
FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
|
FT_ASSERT( !glyphpath->font->hinted ||
|
||||||
glyphpath->hintMap.count == 0 );
|
cf2_hintmap_isValid( glyphpath->hintMap ) ||
|
||||||
|
glyphpath->hintMap->count == 0 );
|
||||||
|
|
||||||
cf2_glyphpath_pushPrevElem( glyphpath,
|
cf2_glyphpath_pushPrevElem( glyphpath,
|
||||||
&glyphpath->hintMap,
|
glyphpath->hintMap,
|
||||||
&P0,
|
&P0,
|
||||||
P1,
|
P1,
|
||||||
FALSE );
|
FALSE );
|
||||||
|
@ -1876,7 +1897,7 @@
|
||||||
|
|
||||||
/* update current map */
|
/* update current map */
|
||||||
if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
|
if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
|
||||||
cf2_hintmap_build( &glyphpath->hintMap,
|
cf2_hintmap_build( glyphpath->hintMap,
|
||||||
glyphpath->hStemHintArray,
|
glyphpath->hStemHintArray,
|
||||||
glyphpath->vStemHintArray,
|
glyphpath->vStemHintArray,
|
||||||
glyphpath->hintMask,
|
glyphpath->hintMask,
|
||||||
|
@ -1907,7 +1928,7 @@
|
||||||
/* empty the final element from the queue and close the path */
|
/* empty the final element from the queue and close the path */
|
||||||
if ( glyphpath->elemIsQueued )
|
if ( glyphpath->elemIsQueued )
|
||||||
cf2_glyphpath_pushPrevElem( glyphpath,
|
cf2_glyphpath_pushPrevElem( glyphpath,
|
||||||
&glyphpath->hintMap,
|
glyphpath->hintMap,
|
||||||
&glyphpath->offsetStart0,
|
&glyphpath->offsetStart0,
|
||||||
glyphpath->offsetStart1,
|
glyphpath->offsetStart1,
|
||||||
TRUE );
|
TRUE );
|
||||||
|
|
|
@ -173,6 +173,16 @@ FT_BEGIN_HEADER
|
||||||
FT_Bool initialMap );
|
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
|
* GlyphPath is a wrapper for drawing operations that scales the
|
||||||
* coordinates according to the render matrix and HintMap. It also tracks
|
* coordinates according to the render matrix and HintMap. It also tracks
|
||||||
|
@ -181,17 +191,15 @@ FT_BEGIN_HEADER
|
||||||
*/
|
*/
|
||||||
typedef struct CF2_GlyphPathRec_
|
typedef struct CF2_GlyphPathRec_
|
||||||
{
|
{
|
||||||
/* TODO: gather some of these into a hinting context */
|
|
||||||
|
|
||||||
CF2_Font font; /* font instance */
|
CF2_Font font; /* font instance */
|
||||||
CF2_OutlineCallbacks callbacks; /* outline consumer */
|
CF2_OutlineCallbacks callbacks; /* outline consumer */
|
||||||
|
|
||||||
|
|
||||||
CF2_HintMapRec hintMap; /* current hint map */
|
CF2_HintMap hintMap; /* ptr to current hint map */
|
||||||
CF2_HintMapRec firstHintMap; /* saved copy */
|
CF2_HintMap firstHintMap; /* ptr to saved copy */
|
||||||
CF2_HintMapRec initialHintMap; /* based on all captured hints */
|
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 scaleX; /* matrix a */
|
||||||
CF2_Fixed scaleC; /* matrix c */
|
CF2_Fixed scaleC; /* matrix c */
|
||||||
|
@ -253,6 +261,7 @@ FT_BEGIN_HEADER
|
||||||
/* CF2_Fixed hShift, */
|
/* CF2_Fixed hShift, */
|
||||||
CF2_ArrStack hStemHintArray,
|
CF2_ArrStack hStemHintArray,
|
||||||
CF2_ArrStack vStemHintArray,
|
CF2_ArrStack vStemHintArray,
|
||||||
|
CF2_HintData hintData,
|
||||||
CF2_HintMask hintMask,
|
CF2_HintMask hintMask,
|
||||||
CF2_Fixed hintOrigin,
|
CF2_Fixed hintOrigin,
|
||||||
const CF2_Blues blues,
|
const CF2_Blues blues,
|
||||||
|
|
|
@ -524,9 +524,9 @@
|
||||||
CF2_ArrStackRec vStemHintArray;
|
CF2_ArrStackRec vStemHintArray;
|
||||||
|
|
||||||
CF2_HintMaskRec hintMask;
|
CF2_HintMaskRec hintMask;
|
||||||
|
CF2_HintDataRec hintData;
|
||||||
CF2_GlyphPathRec glyphPath;
|
CF2_GlyphPathRec glyphPath;
|
||||||
|
|
||||||
|
|
||||||
FT_ZERO( &storage );
|
FT_ZERO( &storage );
|
||||||
FT_ZERO( &results );
|
FT_ZERO( &results );
|
||||||
FT_ZERO( &flexStore );
|
FT_ZERO( &flexStore );
|
||||||
|
@ -560,6 +560,7 @@
|
||||||
/* hShift, */
|
/* hShift, */
|
||||||
&hStemHintArray,
|
&hStemHintArray,
|
||||||
&vStemHintArray,
|
&vStemHintArray,
|
||||||
|
&hintData,
|
||||||
&hintMask,
|
&hintMask,
|
||||||
hintOriginY,
|
hintOriginY,
|
||||||
&font->blues,
|
&font->blues,
|
||||||
|
@ -2504,6 +2505,10 @@
|
||||||
/* `cf2_hintmask_read' (which also traces the mask bytes) */
|
/* `cf2_hintmask_read' (which also traces the mask bytes) */
|
||||||
FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
|
FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
|
||||||
|
|
||||||
|
/* disregard if not hinting */
|
||||||
|
if ( !font->hinted )
|
||||||
|
break;
|
||||||
|
|
||||||
/* never add hints after the mask is computed */
|
/* never add hints after the mask is computed */
|
||||||
if ( cf2_stack_count( opStack ) > 1 &&
|
if ( cf2_stack_count( opStack ) > 1 &&
|
||||||
cf2_hintmask_isValid( &hintMask ) )
|
cf2_hintmask_isValid( &hintMask ) )
|
||||||
|
@ -2553,8 +2558,8 @@
|
||||||
|
|
||||||
cf2_hintmap_init( &counterHintMap,
|
cf2_hintmap_init( &counterHintMap,
|
||||||
font,
|
font,
|
||||||
&glyphPath.initialHintMap,
|
glyphPath.initialHintMap,
|
||||||
&glyphPath.hintMoves,
|
glyphPath.hintMoves,
|
||||||
scaleY );
|
scaleY );
|
||||||
cf2_hintmask_init( &counterMask, error );
|
cf2_hintmask_init( &counterMask, error );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue