[truetype] Simplify bytecode allocations.

To avoid repeated synchronization, some TT_Size allocations are moved
TT_ExecContext for good.  The memory blocks are also consolidated.

* src/truetype/ttinterp.c (TT_{Load,Save,Done}_Context): Remove
synchronization and stack management.
* src/truetype/ttobjs.c (tt_size_{init,done}_bytecode): Manage allocations
and assign them to the execution context.
(tt_size_run_prep): Updated.
This commit is contained in:
Alexei Podtelezhnikov 2025-06-21 23:30:24 -04:00
parent 4c2437efa7
commit c9cbfacb80
3 changed files with 55 additions and 130 deletions

View file

@ -214,10 +214,6 @@
exec->maxPoints = 0;
exec->maxContours = 0;
/* free stack */
FT_FREE( exec->stack );
exec->stackSize = 0;
/* free glyf cvt working area */
FT_FREE( exec->glyfCvt );
exec->glyfCvtSize = 0;
@ -275,27 +271,12 @@
TT_Size size )
{
FT_Int i;
FT_Long stackSize;
FT_Error error;
FT_Memory memory = exec->memory;
exec->face = face;
exec->size = size;
exec->cvtSize = size->cvt_size;
exec->cvt = size->cvt;
exec->storeSize = size->storage_size;
exec->storage = size->storage;
/* XXX: We reserve a little more elements on the stack to deal safely */
/* with broken fonts like arialbs, courbs, timesbs, etc. */
stackSize = face->max_profile.maxStackElements + 32;
if ( FT_QRENEW_ARRAY( exec->stack, exec->stackSize, stackSize ) )
return error;
exec->stackSize = stackSize;
/* free previous glyph code range */
FT_FREE( exec->glyphIns );
exec->glyphSize = 0;
@ -303,15 +284,6 @@
for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
exec->codeRangeTable[i] = size->codeRangeTable[i];
exec->numFDefs = size->num_function_defs;
exec->maxFDefs = size->max_function_defs;
exec->numIDefs = size->num_instruction_defs;
exec->maxIDefs = size->max_instruction_defs;
exec->FDefs = size->function_defs;
exec->IDefs = size->instruction_defs;
exec->maxFunc = size->max_func;
exec->maxIns = size->max_ins;
exec->pointSize = size->point_size;
exec->tt_metrics = size->ttmetrics;
exec->metrics = *size->metrics;
@ -362,12 +334,6 @@
size->GS.scan_control = exec->GS.scan_control;
size->GS.scan_type = exec->GS.scan_type;
size->num_function_defs = exec->numFDefs;
size->num_instruction_defs = exec->numIDefs;
size->max_func = exec->maxFunc;
size->max_ins = exec->maxIns;
for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
size->codeRangeTable[i] = exec->codeRangeTable[i];
}

View file

@ -941,7 +941,7 @@
tt_size_run_prep( TT_Size size )
{
TT_Face face = (TT_Face)size->root.face;
TT_ExecContext exec;
TT_ExecContext exec = size->context;
FT_Error error;
FT_UInt i;
@ -955,24 +955,22 @@
FT_ARRAY_ZERO( size->twilight.cur, size->twilight.n_points );
/* clear storage area */
FT_ARRAY_ZERO( size->storage, size->storage_size );
FT_ARRAY_ZERO( exec->storage, exec->storeSize );
/* Scale the cvt values to the new ppem. */
/* By default, we use the y ppem value for scaling. */
FT_TRACE6(( "CVT values:\n" ));
for ( i = 0; i < size->cvt_size; i++ )
for ( i = 0; i < exec->cvtSize; i++ )
{
/* Unscaled CVT values are already stored in 26.6 format. */
/* Note that this scaling operation is very sensitive to rounding; */
/* the integer division by 64 must be applied to the first argument. */
size->cvt[i] = FT_MulFix( face->cvt[i] / 64, size->ttmetrics.scale );
exec->cvt[i] = FT_MulFix( face->cvt[i] / 64, size->ttmetrics.scale );
FT_TRACE6(( " %3d: %f (%f)\n",
i, (double)face->cvt[i] / 64, (double)size->cvt[i] / 64 ));
i, (double)face->cvt[i] / 64, (double)exec->cvt[i] / 64 ));
}
FT_TRACE6(( "\n" ));
exec = size->context;
error = TT_Load_Context( exec, face, size );
if ( error )
return error;
@ -1010,35 +1008,21 @@
static void
tt_size_done_bytecode( TT_Size size )
{
FT_Memory memory = size->root.face->memory;
FT_Memory memory = size->root.face->memory;
TT_ExecContext exec = size->context;
if ( size->context )
if ( exec )
{
TT_Done_Context( size->context );
FT_FREE( exec->stack );
FT_FREE( exec->FDefs );
TT_Done_Context( exec );
size->context = NULL;
}
FT_FREE( size->cvt );
size->cvt_size = 0;
/* free storage area */
FT_FREE( size->storage );
size->storage_size = 0;
/* twilight zone */
tt_glyphzone_done( memory, &size->twilight );
FT_FREE( size->function_defs );
FT_FREE( size->instruction_defs );
size->num_function_defs = 0;
size->max_function_defs = 0;
size->num_instruction_defs = 0;
size->max_instruction_defs = 0;
size->max_func = 0;
size->max_ins = 0;
}
@ -1054,67 +1038,42 @@
FT_UShort n_twilight;
TT_MaxProfile* maxp = &face->max_profile;
TT_ExecContext exec = size->context;
TT_ExecContext exec;
/* clean up bytecode related data */
FT_FREE( size->function_defs );
FT_FREE( size->instruction_defs );
FT_FREE( size->cvt );
FT_FREE( size->storage );
tt_glyphzone_done( memory, &size->twilight );
if ( exec )
TT_Done_Context( exec );
exec = TT_New_Context( (TT_Driver)face->root.driver );
if ( !exec )
return FT_THROW( Could_Not_Find_Context );
exec->pedantic_hinting = pedantic;
size->context = exec;
size->max_function_defs = maxp->maxFunctionDefs;
size->max_instruction_defs = maxp->maxInstructionDefs;
exec->maxFDefs = maxp->maxFunctionDefs;
exec->maxIDefs = maxp->maxInstructionDefs;
size->num_function_defs = 0;
size->num_instruction_defs = 0;
size->max_func = 0;
size->max_ins = 0;
size->cvt_ready = -1;
size->cvt_size = face->cvt_size;
size->storage_size = maxp->maxStorage;
/* Set default metrics */
{
TT_Size_Metrics* tt_metrics = &size->ttmetrics;
tt_metrics->rotated = FALSE;
tt_metrics->stretched = FALSE;
/* Set default engine compensation. Value 3 is not described */
/* in the OpenType specification (as of Mai 2019), but Greg */
/* says that MS handles it the same as `gray'. */
/* */
/* The Apple specification says that the compensation for */
/* `gray' is always zero. FreeType doesn't do any */
/* compensation at all. */
tt_metrics->compensations[0] = 0; /* gray */
tt_metrics->compensations[1] = 0; /* black */
tt_metrics->compensations[2] = 0; /* white */
tt_metrics->compensations[3] = 0; /* zero */
}
/* allocate function defs, instruction defs, cvt, and storage area */
if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) ||
FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
FT_NEW_ARRAY( size->cvt, size->cvt_size ) ||
FT_NEW_ARRAY( size->storage, size->storage_size ) )
if ( FT_NEW_ARRAY( exec->FDefs, exec->maxFDefs + exec->maxIDefs ) )
goto Exit;
exec->IDefs = exec->FDefs + exec->maxFDefs;
exec->numFDefs = 0;
exec->numIDefs = 0;
exec->maxFunc = 0;
exec->maxIns = 0;
/* XXX: We reserve a little more elements on the stack to deal */
/* with broken fonts like arialbs, courbs, timesbs, etc. */
exec->stackSize = maxp->maxStackElements + 32;
exec->storeSize = maxp->maxStorage;
exec->cvtSize = face->cvt_size;
if ( FT_NEW_ARRAY( exec->stack,
exec->stackSize + exec->storeSize + exec->cvtSize ) )
goto Exit;
exec->storage = exec->stack + exec->stackSize;
exec->cvt = exec->storage + exec->storeSize;
/* reserve twilight zone and set GS before fpgm is executed, */
/* just in case, even though fpgm should not touch them */
n_twilight = maxp->maxTwilightPoints;
@ -1126,7 +1085,24 @@
if ( error )
goto Exit;
size->GS = tt_default_graphics_state;
size->GS = tt_default_graphics_state;
size->cvt_ready = -1;
size->context = exec;
size->ttmetrics.rotated = FALSE;
size->ttmetrics.stretched = FALSE;
/* Set default engine compensation. Value 3 is not described */
/* in the OpenType specification (as of May 2019), but Greg */
/* says that MS handles it the same as `gray'. */
/* */
/* The Apple specification says that the compensation for */
/* `gray' is always zero. FreeType doesn't do any */
/* compensation at all. */
size->ttmetrics.compensations[0] = 0; /* gray */
size->ttmetrics.compensations[1] = 0; /* black */
size->ttmetrics.compensations[2] = 0; /* white */
size->ttmetrics.compensations[3] = 0; /* zero */
/* Fine, now run the font program! */

View file

@ -290,27 +290,10 @@ FT_BEGIN_HEADER
FT_Long point_size; /* for the `MPS' bytecode instruction */
FT_UInt num_function_defs; /* number of function definitions */
FT_UInt max_function_defs;
TT_DefArray function_defs; /* table of function definitions */
FT_UInt num_instruction_defs; /* number of ins. definitions */
FT_UInt max_instruction_defs;
TT_DefArray instruction_defs; /* table of ins. definitions */
FT_UInt max_func;
FT_UInt max_ins;
TT_CodeRangeTable codeRangeTable;
TT_GraphicsState GS;
FT_ULong cvt_size; /* the scaled control value table */
FT_Long* cvt;
FT_UShort storage_size; /* The storage area is now part of */
FT_Long* storage; /* the instance */
TT_GlyphZoneRec twilight; /* The instance's twilight zone */
TT_ExecContext context;