[cff] Change operand stack from fixed size to dynamic

CFF becomes dynamic as well as CFF2
maxstack in Top DICT can increase the CFF2 default from 193
This commit is contained in:
Dave Arnold 2016-11-15 13:57:41 -08:00
parent dfce4760af
commit d49da66dcb
7 changed files with 52 additions and 14 deletions

View File

@ -46,8 +46,8 @@
FT_BEGIN_HEADER
#define CF2_OPERAND_STACK_SIZE 193/* TODO: this is temporary for CFF2 */
#define CF2_CFF2_STACK_SIZE 193
#define CF2_OPERAND_STACK_SIZE 48
#define CF2_MAX_SUBR 16 /* maximum subroutine nesting; */
/* only 10 are allowed but there exist */
/* fonts like `HiraKakuProN-W3.ttf' */

View File

@ -425,6 +425,16 @@
return &decoder->cff->vstore;
}
/* get maxstack value from CFF2 Top DICT */
/* Note: CFF2 Font DICT contains only the default maxstack value */
FT_LOCAL_DEF ( FT_UInt )
cf2_getMaxstack( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->cff );
return decoder->cff->top_font.font_dict.maxstack;
}
/* get normalized design vector for current render request */
/* returns pointer and length */
/* if blend struct is not initialized, return length zero */

View File

@ -67,6 +67,9 @@ FT_BEGIN_HEADER
FT_LOCAL( CFF_VStore )
cf2_getVStore( CFF_Decoder* decoder );
FT_LOCAL_DEF ( FT_UInt )
cf2_getMaxstack( CFF_Decoder* decoder );
FT_LOCAL_DEF( void )
cf2_getNormalizedVector( CFF_Decoder* decoder,

View File

@ -474,6 +474,7 @@
CF2_Fixed hintOriginY = curY;
CF2_Stack opStack = NULL;
FT_UInt stackSize = font->isCFF2 ? CF2_CFF2_STACK_SIZE : CF2_OPERAND_STACK_SIZE;
FT_Byte op1; /* first opcode byte */
CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */
@ -561,7 +562,14 @@
*/
/* allocate an operand stack */
opStack = cf2_stack_init( memory, error );
if ( font->isCFF2 )
{
/* CFF2 font may increase the operand stack size */
FT_UInt maxstack = cf2_getMaxstack( decoder );
if ( maxstack > stackSize )
stackSize = maxstack;
}
opStack = cf2_stack_init( memory, error, stackSize );
if ( !opStack )
{
lastError = FT_THROW( Out_Of_Memory );

View File

@ -51,7 +51,8 @@
/* `error'). */
FT_LOCAL_DEF( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* e )
FT_Error* e,
FT_UInt stackSize )
{
FT_Error error = FT_Err_Ok; /* for FT_QNEW */
@ -63,9 +64,18 @@
/* initialize the structure; FT_QNEW zeroes it */
stack->memory = memory;
stack->error = e;
stack->top = &stack->buffer[0]; /* empty stack */
}
/* allocate the stack buffer */
if ( FT_NEW_ARRAY( stack->buffer, stackSize ) )
{
FT_FREE( stack );
return NULL;
}
stack->stackSize = stackSize;
stack->top = stack->buffer; /* empty stack */
return stack;
}
@ -77,6 +87,8 @@
{
FT_Memory memory = stack->memory;
/* free the buffer */
FT_FREE( stack->buffer );
/* free the main structure */
FT_FREE( stack );
@ -87,7 +99,7 @@
FT_LOCAL_DEF( CF2_UInt )
cf2_stack_count( CF2_Stack stack )
{
return (CF2_UInt)( stack->top - &stack->buffer[0] );
return (CF2_UInt)( stack->top - stack->buffer );
}
@ -95,7 +107,7 @@
cf2_stack_pushInt( CF2_Stack stack,
CF2_Int val )
{
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
if ( stack->top == stack->buffer + stack->stackSize )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
@ -111,7 +123,7 @@
cf2_stack_pushFixed( CF2_Stack stack,
CF2_Fixed val )
{
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
if ( stack->top == stack->buffer + stack->stackSize )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
@ -127,7 +139,7 @@
FT_LOCAL_DEF( CF2_Int )
cf2_stack_popInt( CF2_Stack stack )
{
if ( stack->top == &stack->buffer[0] )
if ( stack->top == stack->buffer )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return 0; /* underflow */
@ -149,7 +161,7 @@
FT_LOCAL_DEF( CF2_Fixed )
cf2_stack_popFixed( CF2_Stack stack )
{
if ( stack->top == &stack->buffer[0] )
if ( stack->top == stack->buffer )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return cf2_intToFixed( 0 ); /* underflow */
@ -175,7 +187,7 @@
cf2_stack_getReal( CF2_Stack stack,
CF2_UInt idx )
{
FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize );
if ( idx >= cf2_stack_count( stack ) )
{
@ -306,7 +318,7 @@
FT_LOCAL_DEF( void )
cf2_stack_clear( CF2_Stack stack )
{
stack->top = &stack->buffer[0];
stack->top = stack->buffer;
}

View File

@ -62,15 +62,17 @@ FT_BEGIN_HEADER
{
FT_Memory memory;
FT_Error* error;
CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE];
CF2_StackNumber* buffer;
CF2_StackNumber* top;
FT_UInt stackSize;
} CF2_StackRec, *CF2_Stack;
FT_LOCAL( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* error );
FT_Error* error,
FT_UInt stackSize );
FT_LOCAL( void )
cf2_stack_free( CF2_Stack stack );

View File

@ -1844,6 +1844,9 @@ Exit:
top->cid_ordering = 0xFFFFU;
top->cid_font_name = 0xFFFFU;
/* set default stack size */
top->maxstack = cff2 ? 193 : 48;
if ( idx->count ) /* count is nonzero for a real index */
error = cff_index_access_element( idx, font_index, &dict, &dict_len );
else