[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
OpenType-1.8
Dave Arnold 8 years ago
parent dfce4760af
commit d49da66dcb
  1. 4
      src/cff/cf2font.h
  2. 10
      src/cff/cf2ft.c
  3. 3
      src/cff/cf2ft.h
  4. 10
      src/cff/cf2intrp.c
  5. 30
      src/cff/cf2stack.c
  6. 6
      src/cff/cf2stack.h
  7. 3
      src/cff/cffload.c

@ -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' */

@ -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 */

@ -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,

@ -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 );

@ -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;
}

@ -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 );

@ -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

Loading…
Cancel
Save