< prev index next >

src/java.desktop/share/native/libfreetype/src/cff/cffparse.c

Print this page

        

@@ -1,43 +1,43 @@
-/***************************************************************************/
-/*                                                                         */
-/*  cffparse.c                                                             */
-/*                                                                         */
-/*    CFF token stream parser (body)                                       */
-/*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * cffparse.c
+ *
+ *   CFF token stream parser (body)
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
 
 
 #include <ft2build.h>
 #include "cffparse.h"
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_CALC_H
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include FT_LIST_H
 
 #include "cfferrs.h"
-#include "cffpic.h"
 #include "cffload.h"
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffparse
+#define FT_COMPONENT  cffparse
 
 
   FT_LOCAL_DEF( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,

@@ -603,11 +603,10 @@
     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
     FT_Matrix*       matrix = &dict->font_matrix;
     FT_Vector*       offset = &dict->font_offset;
     FT_ULong*        upm    = &dict->units_per_em;
     FT_Byte**        data   = parser->stack;
-    FT_Error         error  = FT_ERR( Stack_Underflow );
 
 
     if ( parser->top >= parser->stack + 6 )
     {
       FT_Fixed  values[6];

@@ -615,12 +614,10 @@
 
       FT_Long  min_scaling, max_scaling;
       int      i;
 
 
-      error = FT_Err_Ok;
-
       dict->has_font_matrix = TRUE;
 
       /* We expect a well-formed font matrix, this is, the matrix elements */
       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
       /* loss of precision, we use the magnitude of the largest matrix     */

@@ -645,26 +642,15 @@
       if ( max_scaling < -9                  ||
            max_scaling > 0                   ||
            ( max_scaling - min_scaling ) < 0 ||
            ( max_scaling - min_scaling ) > 9 )
       {
-        /* Return default matrix in case of unlikely values. */
-
         FT_TRACE1(( "cff_parse_font_matrix:"
                     " strange scaling values (minimum %d, maximum %d),\n"
                     "                      "
                     " using default matrix\n", min_scaling, max_scaling ));
-
-        matrix->xx = 0x10000L;
-        matrix->yx = 0;
-        matrix->xy = 0;
-        matrix->yy = 0x10000L;
-        offset->x  = 0;
-        offset->y  = 0;
-        *upm       = 1;
-
-        goto Exit;
+        goto Unlikely;
       }
 
       for ( i = 0; i < 6; i++ )
       {
         FT_Fixed  value = values[i];

@@ -707,14 +693,35 @@
                   (double)matrix->xy / *upm / 65536,
                   (double)matrix->yx / *upm / 65536,
                   (double)matrix->yy / *upm / 65536,
                   (double)offset->x  / *upm / 65536,
                   (double)offset->y  / *upm / 65536 ));
+
+      if ( !FT_Matrix_Check( matrix ) )
+      {
+        FT_TRACE1(( "cff_parse_font_matrix:"
+                    " degenerate values, using default matrix\n" ));
+        goto Unlikely;
     }
 
-  Exit:
-    return error;
+      return FT_Err_Ok;
+    }
+    else
+      return FT_THROW( Stack_Underflow );
+
+  Unlikely:
+    /* Return default matrix in case of unlikely values. */
+
+    matrix->xx = 0x10000L;
+    matrix->yx = 0;
+    matrix->xy = 0;
+    matrix->yy = 0x10000L;
+    offset->x  = 0;
+    offset->y  = 0;
+    *upm       = 1;
+
+    return FT_Err_Ok;
   }
 
 
   static FT_Error
   cff_parse_font_bbox( CFF_Parser  parser )

@@ -800,11 +807,11 @@
     FT_Error         error;
 
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     /* beautify tracing message */
-    if ( ft_trace_levels[FT_COMPONENT] < 4 )
+    if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 )
       FT_TRACE1(( "Multiple Master CFFs not supported yet,"
                   " handling first master design only\n" ));
     else
       FT_TRACE1(( " (not supported yet,"
                   " handling first master design only)\n" ));

@@ -1001,13 +1008,10 @@
           CFF_FIELD( code, name, id, cff_kind_string )
 #define CFF_FIELD_BOOL( code, name, id )             \
           CFF_FIELD( code, name, id, cff_kind_bool )
 
 
-#ifndef FT_CONFIG_OPTION_PIC
-
-
 #undef  CFF_FIELD
 #undef  CFF_FIELD_DELTA
 
 
 #ifndef FT_DEBUG_LEVEL_TRACE

@@ -1116,213 +1120,52 @@
 
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
 
-#else /* FT_CONFIG_OPTION_PIC */
-
-
-  void
-  FT_Destroy_Class_cff_field_handlers( FT_Library          library,
-                                       CFF_Field_Handler*  clazz )
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  static void
+  destruct_t2s_item( FT_Memory  memory,
+                     void*      data,
+                     void*      user )
   {
-    FT_Memory  memory = library->memory;
-
-
-    if ( clazz )
-      FT_FREE( clazz );
+    FT_UNUSED( user );
+    memory->free( memory, data );
   }
-
-
-  FT_Error
-  FT_Create_Class_cff_field_handlers( FT_Library           library,
-                                      CFF_Field_Handler**  output_class )
-  {
-    CFF_Field_Handler*  clazz  = NULL;
-    FT_Error            error;
-    FT_Memory           memory = library->memory;
-
-    int  i = 0;
-
-
-#undef CFF_FIELD
-#define CFF_FIELD( code, name, id, kind ) i++;
-#undef CFF_FIELD_DELTA
-#define CFF_FIELD_DELTA( code, name, max, id ) i++;
-#undef CFF_FIELD_CALLBACK
-#define CFF_FIELD_CALLBACK( code, name, id ) i++;
-#undef CFF_FIELD_BLEND
-#define CFF_FIELD_BLEND( code, id ) i++;
-
-#include "cfftoken.h"
-
-    i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
-
-    if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
-      return error;
-
-    i = 0;
-
-
-#ifndef FT_DEBUG_LEVEL_TRACE
-
-
-#undef CFF_FIELD_CALLBACK
-#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
-          clazz[i].kind         = cff_kind_callback;   \
-          clazz[i].code         = code_ | CFFCODE;     \
-          clazz[i].offset       = 0;                   \
-          clazz[i].size         = 0;                   \
-          clazz[i].reader       = cff_parse_ ## name_; \
-          clazz[i].array_max    = 0;                   \
-          clazz[i].count_offset = 0;                   \
-          i++;
-
-#undef  CFF_FIELD
-#define CFF_FIELD( code_, name_, id_, kind_ )               \
-          clazz[i].kind         = kind_;                    \
-          clazz[i].code         = code_ | CFFCODE;          \
-          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
-          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
-          clazz[i].reader       = 0;                        \
-          clazz[i].array_max    = 0;                        \
-          clazz[i].count_offset = 0;                        \
-          i++;                                              \
-
-#undef  CFF_FIELD_DELTA
-#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
-          clazz[i].kind         = cff_kind_delta;                   \
-          clazz[i].code         = code_ | CFFCODE;                  \
-          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
-          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
-          clazz[i].reader       = 0;                                \
-          clazz[i].array_max    = max_;                             \
-          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
-          i++;
-
-#undef  CFF_FIELD_BLEND
-#define CFF_FIELD_BLEND( code_, id_ )              \
-          clazz[i].kind         = cff_kind_blend;  \
-          clazz[i].code         = code_ | CFFCODE; \
-          clazz[i].offset       = 0;               \
-          clazz[i].size         = 0;               \
-          clazz[i].reader       = cff_parse_blend; \
-          clazz[i].array_max    = 0;               \
-          clazz[i].count_offset = 0;               \
-          i++;
-
-#include "cfftoken.h"
-
-    clazz[i].kind         = 0;
-    clazz[i].code         = 0;
-    clazz[i].offset       = 0;
-    clazz[i].size         = 0;
-    clazz[i].reader       = 0;
-    clazz[i].array_max    = 0;
-    clazz[i].count_offset = 0;
-
-
-#else /* FT_DEBUG_LEVEL_TRACE */
-
-
-#undef CFF_FIELD_CALLBACK
-#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
-          clazz[i].kind         = cff_kind_callback;   \
-          clazz[i].code         = code_ | CFFCODE;     \
-          clazz[i].offset       = 0;                   \
-          clazz[i].size         = 0;                   \
-          clazz[i].reader       = cff_parse_ ## name_; \
-          clazz[i].array_max    = 0;                   \
-          clazz[i].count_offset = 0;                   \
-          clazz[i].id           = id_;                 \
-          i++;
-
-#undef  CFF_FIELD
-#define CFF_FIELD( code_, name_, id_, kind_ )               \
-          clazz[i].kind         = kind_;                    \
-          clazz[i].code         = code_ | CFFCODE;          \
-          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
-          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
-          clazz[i].reader       = 0;                        \
-          clazz[i].array_max    = 0;                        \
-          clazz[i].count_offset = 0;                        \
-          clazz[i].id           = id_;                      \
-          i++;                                              \
-
-#undef  CFF_FIELD_DELTA
-#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
-          clazz[i].kind         = cff_kind_delta;                   \
-          clazz[i].code         = code_ | CFFCODE;                  \
-          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
-          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
-          clazz[i].reader       = 0;                                \
-          clazz[i].array_max    = max_;                             \
-          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
-          clazz[i].id           = id_;                              \
-          i++;
-
-#undef  CFF_FIELD_BLEND
-#define CFF_FIELD_BLEND( code_, id_ )              \
-          clazz[i].kind         = cff_kind_blend;  \
-          clazz[i].code         = code_ | CFFCODE; \
-          clazz[i].offset       = 0;               \
-          clazz[i].size         = 0;               \
-          clazz[i].reader       = cff_parse_blend; \
-          clazz[i].array_max    = 0;               \
-          clazz[i].count_offset = 0;               \
-          clazz[i].id           = id_;             \
-          i++;
-
-#include "cfftoken.h"
-
-    clazz[i].kind         = 0;
-    clazz[i].code         = 0;
-    clazz[i].offset       = 0;
-    clazz[i].size         = 0;
-    clazz[i].reader       = 0;
-    clazz[i].array_max    = 0;
-    clazz[i].count_offset = 0;
-    clazz[i].id           = 0;
-
-
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
-
-    *output_class = clazz;
-
-    return FT_Err_Ok;
-  }
-
-
-#endif /* FT_CONFIG_OPTION_PIC */
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
 
 
   FT_LOCAL_DEF( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
                   FT_Byte*    limit )
   {
+    FT_Byte*  p     = start;
+    FT_Error  error = FT_Err_Ok;
+
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
     PSAux_Service  psaux;
-#endif
 
-    FT_Byte*    p       = start;
-    FT_Error    error   = FT_Err_Ok;
     FT_Library  library = parser->library;
+    FT_Memory   memory  = library->memory;
+
+    FT_ListRec  t2s;
 
-    FT_UNUSED( library );
 
+    FT_ZERO( &t2s );
+#endif
 
     parser->top    = parser->stack;
     parser->start  = start;
     parser->limit  = limit;
     parser->cursor = start;
 
     while ( p < limit )
     {
       FT_UInt  v = *p;
 
+
       /* Opcode 31 is legacy MM T2 operator, not a number.      */
       /* Opcode 255 is reserved and should not appear in fonts; */
       /* it is used internally for CFF2 blends.                 */
       if ( v >= 27 && v != 31 && v != 255 )
       {

@@ -1368,10 +1211,11 @@
         CFF_FontRec  cff_rec;
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
         FT_Fixed*  stack;
+        FT_ListNode  node;
         FT_Byte*   q;
 
 
         charstring_base = ++p;
 

@@ -1403,21 +1247,33 @@
           goto Exit;
         }
 
         error = psaux->cff_decoder_funcs->parse_charstrings_old(
                   &decoder, charstring_base, charstring_len, 1 );
+        if ( error )
+          goto Exit;
 
         /* Now copy the stack data in the temporary decoder object,    */
         /* converting it back to charstring number representations     */
         /* (this is ugly, I know).                                     */
-        /*                                                             */
-        /* We overwrite the original top DICT charstring under the     */
-        /* assumption that the charstring representation of the result */
-        /* of `cff_decoder_parse_charstrings' is shorter, which should */
-        /* be always true.                                             */
 
-        q     = charstring_base - 1;
+        node = (FT_ListNode)memory->alloc( memory,
+                                           sizeof ( FT_ListNodeRec ) );
+        if ( !node )
+          goto Out_Of_Memory_Error;
+
+        /* `5' is the conservative upper bound of required bytes per stack */
+        /* element.                                                        */
+        q = (FT_Byte*)memory->alloc( memory,
+                                     5 * ( decoder.top - decoder.stack ) );
+        if ( !q )
+          goto Out_Of_Memory_Error;
+
+        node->data = q;
+
+        FT_List_Add( &t2s, node );
+
         stack = decoder.stack;
 
         while ( stack < decoder.top )
         {
           FT_ULong  num;

@@ -1429,11 +1285,11 @@
 
           *parser->top++ = q;
 
           if ( *stack < 0 )
           {
-            num = (FT_ULong)-*stack;
+            num = (FT_ULong)NEG_LONG( *stack );
             neg = 1;
           }
           else
           {
             num = (FT_ULong)*stack;

@@ -1521,11 +1377,11 @@
 
           code = 0x100 | p[0];
         }
         code = code | parser->object_code;
 
-        for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
+        for ( field = cff_field_handlers; field->kind; field++ )
         {
           if ( field->code == (FT_Int)code )
           {
             /* we found our field's handler; read it */
             FT_Long   val;

@@ -1670,15 +1526,24 @@
         /*       but we don't have access to subFont */
         if ( field->kind != cff_kind_blend )
           parser->top = parser->stack;
       }
       p++;
-    }
+    } /* while ( p < limit ) */
 
   Exit:
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
+#endif
     return error;
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  Out_Of_Memory_Error:
+    error = FT_THROW( Out_Of_Memory );
+    goto Exit;
+#endif
+
   Stack_Overflow:
     error = FT_THROW( Invalid_Argument );
     goto Exit;
 
   Stack_Underflow:
< prev index next >