shithub: freetype+ttf2subf

Download patch

ref: 010e0614f2effe058855aacfc3e61c71e1cb5739
parent: 41533b958cca73ed8f0e12ec4b38f1369e4e9ee3
author: Dave Arnold <[email protected]>
date: Thu Dec 15 06:22:15 EST 2016

[cff] Implement dynamic stack size for Adobe engine.

This also adds `cf2_stack_setReal' and `cf2_stack_pop', needed for
the forthcoming CFF2 support.

* src/cff/cf2stack.c (cf2_stack_init): Add argument for stack size.
(cf2_stack_free): Deallocate stack.
(cf2_stack_count, cf2_stack_pushInt, cf2_stack_pushFixed,
cf2_stack_popInt, cf2_stack_popFixed, cf2_stack_getReal,
cf2_stack_clear): Updated.
(cf2_stack_setReal, cf2_stack_pop): New functions.

* src/cff/cf2stack.h (CF2_Stack): Add `stackSize' member.
Update function declarations.

* src/cff/cf2intrp.c (cf2_interpT2CharString): Updated.

* src/cff/cffparse.c (cff_parser_init): Add parameter for stack
size; return error code.
(cff_parser_done): New function.
(cff_parser_run): Updated.

* src/cff/cffparse.h (CFF_Parser): Add `stackSize' member and make
`stack' a pointer.
Update function declarations.

* src/cff/cffload.c (cff_load_private_dict, cff_subfont_load):
Updated.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,35 @@
 2016-12-15  Dave Arnold  <[email protected]>
+
+	[cff] Implement dynamic stack size for Adobe engine.
+
+	This also adds `cf2_stack_setReal' and `cf2_stack_pop', needed for
+	the forthcoming CFF2 support.
+
+	* src/cff/cf2stack.c (cf2_stack_init): Add argument for stack size.
+	(cf2_stack_free): Deallocate stack.
+	(cf2_stack_count, cf2_stack_pushInt, cf2_stack_pushFixed,
+	cf2_stack_popInt, cf2_stack_popFixed, cf2_stack_getReal,
+	cf2_stack_clear): Updated.
+	(cf2_stack_setReal, cf2_stack_pop): New functions.
+
+	* src/cff/cf2stack.h (CF2_Stack): Add `stackSize' member.
+	Update function declarations.
+
+	* src/cff/cf2intrp.c (cf2_interpT2CharString): Updated.
+
+	* src/cff/cffparse.c (cff_parser_init): Add parameter for stack
+	size; return error code.
+	(cff_parser_done): New function.
+	(cff_parser_run): Updated.
+
+	* src/cff/cffparse.h (CFF_Parser): Add `stackSize' member and make
+	`stack' a pointer.
+	Update function declarations.
+
+	* src/cff/cffload.c (cff_load_private_dict, cff_subfont_load):
+	Updated.
+
+2016-12-15  Dave Arnold  <[email protected]>
 	    Werner Lemberg  <[email protected]>
 
 	[cff] Code shuffling.
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -532,7 +532,7 @@
      */
 
     /* allocate an operand stack */
-    opStack = cf2_stack_init( memory, error );
+    opStack = cf2_stack_init( memory, error, CF2_OPERAND_STACK_SIZE );
     if ( !opStack )
     {
       lastError = FT_THROW( Out_Of_Memory );
--- 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_NEW */
 
@@ -63,9 +64,18 @@
       /* initialize the structure; FT_NEW 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 ) )
     {
@@ -195,7 +207,38 @@
   }
 
 
-  FT_LOCAL( void )
+  /* provide random access to stack */
+  FT_LOCAL_DEF( void )
+  cf2_stack_setReal( CF2_Stack  stack,
+                     CF2_UInt   idx,
+                     CF2_Fixed  val )
+  {
+    if ( idx > cf2_stack_count( stack ) )
+    {
+      CF2_SET_ERROR( stack->error, Stack_Overflow );
+      return;
+    }
+
+    stack->buffer[idx].u.r  = val;
+    stack->buffer[idx].type = CF2_NumberFixed;
+  }
+
+
+  /* discard (pop) num values from stack */
+  FT_LOCAL_DEF( void )
+  cf2_stack_pop( CF2_Stack  stack,
+                 CF2_UInt   num )
+  {
+    if ( num > cf2_stack_count( stack ) )
+    {
+      CF2_SET_ERROR( stack->error, Stack_Underflow );
+      return;
+    }
+    stack->top -= num;
+  }
+
+
+  FT_LOCAL_DEF( void )
   cf2_stack_roll( CF2_Stack  stack,
                   CF2_Int    count,
                   CF2_Int    shift )
@@ -278,7 +321,7 @@
   FT_LOCAL_DEF( void )
   cf2_stack_clear( CF2_Stack  stack )
   {
-    stack->top = &stack->buffer[0];
+    stack->top = stack->buffer;
   }
 
 
--- a/src/cff/cf2stack.h
+++ b/src/cff/cf2stack.h
@@ -62,8 +62,9 @@
   {
     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;
 
@@ -70,7 +71,8 @@
 
   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 );
 
@@ -92,6 +94,14 @@
   FT_LOCAL( CF2_Fixed )
   cf2_stack_getReal( CF2_Stack  stack,
                      CF2_UInt   idx );
+  FT_LOCAL( void )
+  cf2_stack_setReal( CF2_Stack  stack,
+                     CF2_UInt   idx,
+                     CF2_Fixed  val );
+
+  FT_LOCAL( void )
+  cf2_stack_pop( CF2_Stack  stack,
+                 CF2_UInt   num );
 
   FT_LOCAL( void )
   cf2_stack_roll( CF2_Stack  stack,
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1341,11 +1341,11 @@
     CFF_FontRecDict  top    = &subfont->font_dict;
     CFF_Private      priv   = &subfont->private_dict;
     FT_Stream        stream = font->stream;
+    FT_UInt          stackSize;
 
 
-    /* parse the private dictionary, if any */
     if ( !top->private_offset || !top->private_size )
-      goto Exit;
+      goto Exit2;       /* no private DICT, do nothing */
 
     /* set defaults */
     FT_ZERO( priv );
@@ -1356,13 +1356,17 @@
     priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
     priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
 
-    cff_parser_init( &parser,
-                     CFF_CODE_PRIVATE,
-                     priv,
-                     font->library,
-                     top->num_designs,
-                     top->num_axes );
+    stackSize = CFF_MAX_STACK_DEPTH + 1;
 
+    if ( cff_parser_init( &parser,
+                          CFF_CODE_PRIVATE,
+                          priv,
+                          font->library,
+                          stackSize,
+                          top->num_designs,
+                          top->num_axes ) )
+      goto Exit;
+
     if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
          FT_FRAME_ENTER( top->private_size )                       )
       goto Exit;
@@ -1380,6 +1384,11 @@
     priv->num_blue_values &= ~1;
 
   Exit:
+    /* clean up */
+    cff_parser_done( &parser ); /* free parser stack */
+
+  Exit2:
+    /* no clean up (parser not initialized) */
     return error;
   }
 
@@ -1399,14 +1408,18 @@
     CFF_FontRecDict  top  = &subfont->font_dict;
     CFF_Private      priv = &subfont->private_dict;
 
+    FT_UInt  stackSize = CFF_MAX_STACK_DEPTH;
 
-    cff_parser_init( &parser,
-                     CFF_CODE_TOPDICT,
-                     &subfont->font_dict,
-                     font->library,
-                     0,
-                     0 );
 
+    if ( cff_parser_init( &parser,
+                          CFF_CODE_TOPDICT,
+                          &subfont->font_dict,
+                          font->library,
+                          stackSize,
+                          0,
+                          0 ) )
+      goto Exit;
+
     /* set defaults */
     FT_ZERO( top );
 
@@ -1470,6 +1483,8 @@
     }
 
   Exit:
+    cff_parser_done( &parser ); /* free parser stack */
+
     return error;
   }
 
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -36,25 +36,55 @@
 #define FT_COMPONENT  trace_cffparse
 
 
-  FT_LOCAL_DEF( void )
+  FT_LOCAL_DEF( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes )
   {
+    FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
+    FT_Error   error;                       /* for FT_NEW_ARRAY */
+
+
     FT_ZERO( parser );
 
+#if 0
     parser->top         = parser->stack;
+#endif
     parser->object_code = code;
     parser->object      = object;
     parser->library     = library;
     parser->num_designs = num_designs;
     parser->num_axes    = num_axes;
+
+    /* allocate the stack buffer */
+    if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
+    {
+      FT_FREE( parser->stack );
+      goto Exit;
+    }
+
+    parser->stackSize = stackSize;
+    parser->top       = parser->stack;    /* empty stack */
+
+  Exit:
+    return error;
   }
 
 
+  FT_LOCAL_DEF( void )
+  cff_parser_done( CFF_Parser  parser )
+  {
+    FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
+
+
+    FT_FREE( parser->stack );
+  }
+
+
   /* read an integer */
   static FT_Long
   cff_parse_integer( FT_Byte*  start,
@@ -1071,7 +1101,7 @@
       if ( v >= 27 && v != 31 )
       {
         /* it's a number; we will push its position on the stack */
-        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
           goto Stack_Overflow;
 
         *parser->top++ = p;
@@ -1162,7 +1192,7 @@
           FT_Bool   neg;
 
 
-          if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+          if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
             goto Stack_Overflow;
 
           *parser->top++ = q;
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -41,8 +41,9 @@
     FT_Byte*    limit;
     FT_Byte*    cursor;
 
-    FT_Byte*    stack[CFF_MAX_STACK_DEPTH + 1];
+    FT_Byte**   stack;
     FT_Byte**   top;
+    FT_UInt     stackSize;  /* allocated size */
 
     FT_UInt     object_code;
     void*       object;
@@ -53,13 +54,17 @@
   } CFF_ParserRec, *CFF_Parser;
 
 
-  FT_LOCAL( void )
+  FT_LOCAL( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes );
+
+  FT_LOCAL( void )
+  cff_parser_done( CFF_Parser  parser );
 
   FT_LOCAL( FT_Error )
   cff_parser_run( CFF_Parser  parser,