[truetype] Simplify memory management.
Instead of using `Update_Max`, switch to regular FreeType memory allocation macros, stop pre-allocating the glyph instruction arrays. * src/truetype/ttgload.c (TT_Load_Simple_Glyph, TT_Process_Composite_Glyph): Switch to regular memory allocation. * src/truetype/ttinterp.c (Update_Max): Removed. (TT_Load_Context): Reallocate stack and free old instructions. (Modify_CVT_Check, Ins_WS): Switch to regular memory allocation. * src/truetype/ttinterp.h (Update_Max): Removed.
This commit is contained in:
parent
b2a9490623
commit
de94e2cbfb
|
@ -437,7 +437,8 @@
|
||||||
|
|
||||||
if ( IS_HINTED( load->load_flags ) )
|
if ( IS_HINTED( load->load_flags ) )
|
||||||
{
|
{
|
||||||
FT_ULong tmp;
|
TT_ExecContext exec = load->exec;
|
||||||
|
FT_Memory memory = exec->memory;
|
||||||
|
|
||||||
|
|
||||||
/* check instructions size */
|
/* check instructions size */
|
||||||
|
@ -449,24 +450,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */
|
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */
|
||||||
/* and thus update the bytecode array size by ourselves */
|
/* and thus allocate the bytecode array size by ourselves */
|
||||||
|
|
||||||
tmp = load->exec->glyphSize;
|
|
||||||
error = Update_Max( load->exec->memory,
|
|
||||||
&tmp,
|
|
||||||
sizeof ( FT_Byte ),
|
|
||||||
(void*)&load->exec->glyphIns,
|
|
||||||
n_ins );
|
|
||||||
|
|
||||||
load->exec->glyphSize = (FT_UInt)tmp;
|
|
||||||
if ( error )
|
|
||||||
return error;
|
|
||||||
|
|
||||||
load->glyph->control_len = n_ins;
|
|
||||||
load->glyph->control_data = load->exec->glyphIns;
|
|
||||||
|
|
||||||
if ( n_ins )
|
if ( n_ins )
|
||||||
FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
|
{
|
||||||
|
if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins );
|
||||||
|
|
||||||
|
exec->glyphSize = n_ins;
|
||||||
|
|
||||||
|
load->glyph->control_len = n_ins;
|
||||||
|
load->glyph->control_data = exec->glyphIns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||||
|
@ -1331,12 +1327,12 @@
|
||||||
FT_UInt start_contour )
|
FT_UInt start_contour )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
FT_Outline* outline;
|
FT_Outline* outline = &loader->gloader->base.outline;
|
||||||
|
FT_Stream stream = loader->stream;
|
||||||
|
FT_UShort n_ins;
|
||||||
FT_UInt i;
|
FT_UInt i;
|
||||||
|
|
||||||
|
|
||||||
outline = &loader->gloader->base.outline;
|
|
||||||
|
|
||||||
/* make room for phantom points */
|
/* make room for phantom points */
|
||||||
error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
|
error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
|
||||||
outline->n_points + 4,
|
outline->n_points + 4,
|
||||||
|
@ -1351,53 +1347,40 @@
|
||||||
|
|
||||||
#ifdef TT_USE_BYTECODE_INTERPRETER
|
#ifdef TT_USE_BYTECODE_INTERPRETER
|
||||||
|
|
||||||
|
/* TT_Load_Composite_Glyph only gives us the offset of instructions */
|
||||||
|
/* so we read them here */
|
||||||
|
if ( FT_STREAM_SEEK( loader->ins_pos ) ||
|
||||||
|
FT_READ_USHORT( n_ins ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
|
||||||
|
|
||||||
|
if ( !n_ins )
|
||||||
|
return FT_Err_Ok;
|
||||||
|
|
||||||
|
/* don't trust `maxSizeOfInstructions'; */
|
||||||
|
/* only do a rough safety check */
|
||||||
|
if ( n_ins > loader->byte_len )
|
||||||
{
|
{
|
||||||
FT_Stream stream = loader->stream;
|
FT_TRACE1(( "TT_Process_Composite_Glyph:"
|
||||||
FT_UShort n_ins, max_ins;
|
" too many instructions (%hu) for glyph with length %u\n",
|
||||||
FT_ULong tmp;
|
n_ins, loader->byte_len ));
|
||||||
|
return FT_THROW( Too_Many_Hints );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TT_ExecContext exec = loader->exec;
|
||||||
|
FT_Memory memory = exec->memory;
|
||||||
|
|
||||||
|
|
||||||
/* TT_Load_Composite_Glyph only gives us the offset of instructions */
|
if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ||
|
||||||
/* so we read them here */
|
FT_STREAM_READ( exec->glyphIns, n_ins ) )
|
||||||
if ( FT_STREAM_SEEK( loader->ins_pos ) ||
|
|
||||||
FT_READ_USHORT( n_ins ) )
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
|
exec->glyphSize = n_ins;
|
||||||
|
|
||||||
/* check it */
|
|
||||||
max_ins = loader->face->max_profile.maxSizeOfInstructions;
|
|
||||||
if ( n_ins > max_ins )
|
|
||||||
{
|
|
||||||
/* don't trust `maxSizeOfInstructions'; */
|
|
||||||
/* only do a rough safety check */
|
|
||||||
if ( n_ins > loader->byte_len )
|
|
||||||
{
|
|
||||||
FT_TRACE1(( "TT_Process_Composite_Glyph:"
|
|
||||||
" too many instructions (%hu) for glyph with length %u\n",
|
|
||||||
n_ins, loader->byte_len ));
|
|
||||||
return FT_THROW( Too_Many_Hints );
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = loader->exec->glyphSize;
|
|
||||||
error = Update_Max( loader->exec->memory,
|
|
||||||
&tmp,
|
|
||||||
sizeof ( FT_Byte ),
|
|
||||||
(void*)&loader->exec->glyphIns,
|
|
||||||
n_ins );
|
|
||||||
|
|
||||||
loader->exec->glyphSize = (FT_UShort)tmp;
|
|
||||||
if ( error )
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
else if ( n_ins == 0 )
|
|
||||||
return FT_Err_Ok;
|
|
||||||
|
|
||||||
if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
|
|
||||||
return error;
|
|
||||||
|
|
||||||
loader->glyph->control_data = loader->exec->glyphIns;
|
|
||||||
loader->glyph->control_len = n_ins;
|
loader->glyph->control_len = n_ins;
|
||||||
|
loader->glyph->control_data = exec->glyphIns;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -275,57 +275,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* @Function:
|
|
||||||
* Update_Max
|
|
||||||
*
|
|
||||||
* @Description:
|
|
||||||
* Checks the size of a buffer and reallocates it if necessary.
|
|
||||||
*
|
|
||||||
* @Input:
|
|
||||||
* memory ::
|
|
||||||
* A handle to the parent memory object.
|
|
||||||
*
|
|
||||||
* multiplier ::
|
|
||||||
* The size in bytes of each element in the buffer.
|
|
||||||
*
|
|
||||||
* new_max ::
|
|
||||||
* The new capacity (size) of the buffer.
|
|
||||||
*
|
|
||||||
* @InOut:
|
|
||||||
* size ::
|
|
||||||
* The address of the buffer's current size expressed
|
|
||||||
* in elements.
|
|
||||||
*
|
|
||||||
* buff ::
|
|
||||||
* The address of the buffer base pointer.
|
|
||||||
*
|
|
||||||
* @Return:
|
|
||||||
* FreeType error code. 0 means success.
|
|
||||||
*/
|
|
||||||
FT_LOCAL_DEF( FT_Error )
|
|
||||||
Update_Max( FT_Memory memory,
|
|
||||||
FT_ULong* size,
|
|
||||||
FT_ULong multiplier,
|
|
||||||
void* _pbuff,
|
|
||||||
FT_ULong new_max )
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
void** pbuff = (void**)_pbuff;
|
|
||||||
|
|
||||||
|
|
||||||
if ( *size < new_max )
|
|
||||||
{
|
|
||||||
if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
|
|
||||||
return error;
|
|
||||||
*size = new_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FT_Err_Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* @Function:
|
* @Function:
|
||||||
|
@ -359,9 +308,9 @@
|
||||||
TT_Size size )
|
TT_Size size )
|
||||||
{
|
{
|
||||||
FT_Int i;
|
FT_Int i;
|
||||||
FT_ULong tmp;
|
|
||||||
TT_MaxProfile* maxp;
|
TT_MaxProfile* maxp;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
FT_Memory memory = exec->memory;
|
||||||
|
|
||||||
|
|
||||||
exec->face = face;
|
exec->face = face;
|
||||||
|
@ -406,25 +355,15 @@
|
||||||
|
|
||||||
/* XXX: We reserve a little more elements on the stack to deal safely */
|
/* XXX: We reserve a little more elements on the stack to deal safely */
|
||||||
/* with broken fonts like arialbs, courbs, timesbs, etc. */
|
/* with broken fonts like arialbs, courbs, timesbs, etc. */
|
||||||
tmp = (FT_ULong)exec->stackSize;
|
if ( FT_QRENEW_ARRAY( exec->stack,
|
||||||
error = Update_Max( exec->memory,
|
exec->stackSize,
|
||||||
&tmp,
|
maxp->maxStackElements + 32 ) )
|
||||||
sizeof ( FT_F26Dot6 ),
|
|
||||||
(void*)&exec->stack,
|
|
||||||
maxp->maxStackElements + 32 );
|
|
||||||
exec->stackSize = (FT_Long)tmp;
|
|
||||||
if ( error )
|
|
||||||
return error;
|
return error;
|
||||||
|
exec->stackSize = maxp->maxStackElements + 32;
|
||||||
|
|
||||||
tmp = (FT_ULong)exec->glyphSize;
|
/* free previous glyph code range */
|
||||||
error = Update_Max( exec->memory,
|
FT_FREE( exec->glyphIns );
|
||||||
&tmp,
|
exec->glyphSize = 0;
|
||||||
sizeof ( FT_Byte ),
|
|
||||||
(void*)&exec->glyphIns,
|
|
||||||
maxp->maxSizeOfInstructions );
|
|
||||||
exec->glyphSize = (FT_UInt)tmp;
|
|
||||||
if ( error )
|
|
||||||
return error;
|
|
||||||
|
|
||||||
exec->pts.n_points = 0;
|
exec->pts.n_points = 0;
|
||||||
exec->pts.n_contours = 0;
|
exec->pts.n_contours = 0;
|
||||||
|
@ -1530,14 +1469,16 @@
|
||||||
if ( exc->iniRange == tt_coderange_glyph &&
|
if ( exc->iniRange == tt_coderange_glyph &&
|
||||||
exc->cvt != exc->glyfCvt )
|
exc->cvt != exc->glyfCvt )
|
||||||
{
|
{
|
||||||
exc->error = Update_Max( exc->memory,
|
FT_Memory memory = exc->memory;
|
||||||
&exc->glyfCvtSize,
|
FT_Error error;
|
||||||
sizeof ( FT_Long ),
|
|
||||||
(void*)&exc->glyfCvt,
|
|
||||||
exc->cvtSize );
|
FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
|
||||||
if ( exc->error )
|
exc->error = error;
|
||||||
|
if ( error )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
exc->glyfCvtSize = exc->cvtSize;
|
||||||
FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
|
FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
|
||||||
exc->cvt = exc->glyfCvt;
|
exc->cvt = exc->glyfCvt;
|
||||||
}
|
}
|
||||||
|
@ -3117,18 +3058,18 @@
|
||||||
if ( exc->iniRange == tt_coderange_glyph &&
|
if ( exc->iniRange == tt_coderange_glyph &&
|
||||||
exc->storage != exc->glyfStorage )
|
exc->storage != exc->glyfStorage )
|
||||||
{
|
{
|
||||||
FT_ULong tmp = (FT_ULong)exc->glyfStoreSize;
|
FT_Memory memory = exc->memory;
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
|
||||||
exc->error = Update_Max( exc->memory,
|
FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
|
||||||
&tmp,
|
exc->glyfStoreSize,
|
||||||
sizeof ( FT_Long ),
|
exc->storeSize );
|
||||||
(void*)&exc->glyfStorage,
|
exc->error = error;
|
||||||
exc->storeSize );
|
if ( error )
|
||||||
exc->glyfStoreSize = (FT_UShort)tmp;
|
|
||||||
if ( exc->error )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
exc->glyfStoreSize = exc->storeSize;
|
||||||
FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
|
FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
|
||||||
exc->storage = exc->glyfStorage;
|
exc->storage = exc->glyfStorage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,14 +460,6 @@ FT_BEGIN_HEADER
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( void )
|
||||||
TT_Clear_CodeRange( TT_ExecContext exec,
|
TT_Clear_CodeRange( TT_ExecContext exec,
|
||||||
FT_Int range );
|
FT_Int range );
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL( FT_Error )
|
|
||||||
Update_Max( FT_Memory memory,
|
|
||||||
FT_ULong* size,
|
|
||||||
FT_ULong multiplier,
|
|
||||||
void* _pbuff,
|
|
||||||
FT_ULong new_max );
|
|
||||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue