freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] OpenType-1.8 d49da66 5/6: [cff] Change operand stack from fi


From: Dave Arnold
Subject: [freetype2] OpenType-1.8 d49da66 5/6: [cff] Change operand stack from fixed size to dynamic
Date: Thu, 17 Nov 2016 16:23:03 +0000 (UTC)

branch: OpenType-1.8
commit d49da66dcb60b0b11673eb42fa89de1bc6a20c8c
Author: Dave Arnold <address@hidden>
Commit: Dave Arnold <address@hidden>

    [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
---
 src/cff/cf2font.h  |    4 ++--
 src/cff/cf2ft.c    |   10 ++++++++++
 src/cff/cf2ft.h    |    3 +++
 src/cff/cf2intrp.c |   10 +++++++++-
 src/cff/cf2stack.c |   30 +++++++++++++++++++++---------
 src/cff/cf2stack.h |    6 ++++--
 src/cff/cffload.c  |    3 +++
 7 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/src/cff/cf2font.h b/src/cff/cf2font.h
index c86b8f8..32063c7 100644
--- a/src/cff/cf2font.h
+++ b/src/cff/cf2font.h
@@ -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'    */
diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c
index fd95a6b..93c5383 100644
--- a/src/cff/cf2ft.c
+++ b/src/cff/cf2ft.c
@@ -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  */
diff --git a/src/cff/cf2ft.h b/src/cff/cf2ft.h
index 7c1311a..c5dbba0 100644
--- a/src/cff/cf2ft.h
+++ b/src/cff/cf2ft.h
@@ -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,
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 0cbee55..9b19077 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -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 );
diff --git a/src/cff/cf2stack.c b/src/cff/cf2stack.c
index 5001b68..0634850 100644
--- a/src/cff/cf2stack.c
+++ b/src/cff/cf2stack.c
@@ -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;
   }
 
 
diff --git a/src/cff/cf2stack.h b/src/cff/cf2stack.h
index acec074..03de345 100644
--- a/src/cff/cf2stack.h
+++ b/src/cff/cf2stack.h
@@ -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 );
 
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index fd0162f..4c65c94 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]