Home | History | Annotate | Download | only in cff
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  cffparse.c                                                             */
      4 /*                                                                         */
      5 /*    CFF token stream parser (body)                                       */
      6 /*                                                                         */
      7 /*  Copyright 1996-2004, 2007-2011 by                                      */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include <ft2build.h>
     20 #include "cffparse.h"
     21 #include FT_INTERNAL_STREAM_H
     22 #include FT_INTERNAL_DEBUG_H
     23 
     24 #include "cfferrs.h"
     25 #include "cffpic.h"
     26 
     27 
     28   /*************************************************************************/
     29   /*                                                                       */
     30   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     31   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     32   /* messages during execution.                                            */
     33   /*                                                                       */
     34 #undef  FT_COMPONENT
     35 #define FT_COMPONENT  trace_cffparse
     36 
     37 
     38   FT_LOCAL_DEF( void )
     39   cff_parser_init( CFF_Parser  parser,
     40                    FT_UInt     code,
     41                    void*       object,
     42                    FT_Library  library)
     43   {
     44     FT_MEM_ZERO( parser, sizeof ( *parser ) );
     45 
     46     parser->top         = parser->stack;
     47     parser->object_code = code;
     48     parser->object      = object;
     49     parser->library     = library;
     50   }
     51 
     52 
     53   /* read an integer */
     54   static FT_Long
     55   cff_parse_integer( FT_Byte*  start,
     56                      FT_Byte*  limit )
     57   {
     58     FT_Byte*  p   = start;
     59     FT_Int    v   = *p++;
     60     FT_Long   val = 0;
     61 
     62 
     63     if ( v == 28 )
     64     {
     65       if ( p + 2 > limit )
     66         goto Bad;
     67 
     68       val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
     69       p  += 2;
     70     }
     71     else if ( v == 29 )
     72     {
     73       if ( p + 4 > limit )
     74         goto Bad;
     75 
     76       val = ( (FT_Long)p[0] << 24 ) |
     77             ( (FT_Long)p[1] << 16 ) |
     78             ( (FT_Long)p[2] <<  8 ) |
     79                        p[3];
     80       p += 4;
     81     }
     82     else if ( v < 247 )
     83     {
     84       val = v - 139;
     85     }
     86     else if ( v < 251 )
     87     {
     88       if ( p + 1 > limit )
     89         goto Bad;
     90 
     91       val = ( v - 247 ) * 256 + p[0] + 108;
     92       p++;
     93     }
     94     else
     95     {
     96       if ( p + 1 > limit )
     97         goto Bad;
     98 
     99       val = -( v - 251 ) * 256 - p[0] - 108;
    100       p++;
    101     }
    102 
    103   Exit:
    104     return val;
    105 
    106   Bad:
    107     val = 0;
    108     goto Exit;
    109   }
    110 
    111 
    112   static const FT_Long power_tens[] =
    113   {
    114     1L,
    115     10L,
    116     100L,
    117     1000L,
    118     10000L,
    119     100000L,
    120     1000000L,
    121     10000000L,
    122     100000000L,
    123     1000000000L
    124   };
    125 
    126 
    127   /* read a real */
    128   static FT_Fixed
    129   cff_parse_real( FT_Byte*  start,
    130                   FT_Byte*  limit,
    131                   FT_Long   power_ten,
    132                   FT_Long*  scaling )
    133   {
    134     FT_Byte*  p = start;
    135     FT_UInt   nib;
    136     FT_UInt   phase;
    137 
    138     FT_Long   result, number, exponent;
    139     FT_Int    sign = 0, exponent_sign = 0;
    140     FT_Long   exponent_add, integer_length, fraction_length;
    141 
    142 
    143     if ( scaling )
    144       *scaling = 0;
    145 
    146     result = 0;
    147 
    148     number   = 0;
    149     exponent = 0;
    150 
    151     exponent_add    = 0;
    152     integer_length  = 0;
    153     fraction_length = 0;
    154 
    155     /* First of all, read the integer part. */
    156     phase = 4;
    157 
    158     for (;;)
    159     {
    160       /* If we entered this iteration with phase == 4, we need to */
    161       /* read a new byte.  This also skips past the initial 0x1E. */
    162       if ( phase )
    163       {
    164         p++;
    165 
    166         /* Make sure we don't read past the end. */
    167         if ( p >= limit )
    168           goto Exit;
    169       }
    170 
    171       /* Get the nibble. */
    172       nib   = ( p[0] >> phase ) & 0xF;
    173       phase = 4 - phase;
    174 
    175       if ( nib == 0xE )
    176         sign = 1;
    177       else if ( nib > 9 )
    178         break;
    179       else
    180       {
    181         /* Increase exponent if we can't add the digit. */
    182         if ( number >= 0xCCCCCCCL )
    183           exponent_add++;
    184         /* Skip leading zeros. */
    185         else if ( nib || number )
    186         {
    187           integer_length++;
    188           number = number * 10 + nib;
    189         }
    190       }
    191     }
    192 
    193     /* Read fraction part, if any. */
    194     if ( nib == 0xa )
    195       for (;;)
    196       {
    197         /* If we entered this iteration with phase == 4, we need */
    198         /* to read a new byte.                                   */
    199         if ( phase )
    200         {
    201           p++;
    202 
    203           /* Make sure we don't read past the end. */
    204           if ( p >= limit )
    205             goto Exit;
    206         }
    207 
    208         /* Get the nibble. */
    209         nib   = ( p[0] >> phase ) & 0xF;
    210         phase = 4 - phase;
    211         if ( nib >= 10 )
    212           break;
    213 
    214         /* Skip leading zeros if possible. */
    215         if ( !nib && !number )
    216           exponent_add--;
    217         /* Only add digit if we don't overflow. */
    218         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
    219         {
    220           fraction_length++;
    221           number = number * 10 + nib;
    222         }
    223       }
    224 
    225     /* Read exponent, if any. */
    226     if ( nib == 12 )
    227     {
    228       exponent_sign = 1;
    229       nib           = 11;
    230     }
    231 
    232     if ( nib == 11 )
    233     {
    234       for (;;)
    235       {
    236         /* If we entered this iteration with phase == 4, */
    237         /* we need to read a new byte.                   */
    238         if ( phase )
    239         {
    240           p++;
    241 
    242           /* Make sure we don't read past the end. */
    243           if ( p >= limit )
    244             goto Exit;
    245         }
    246 
    247         /* Get the nibble. */
    248         nib   = ( p[0] >> phase ) & 0xF;
    249         phase = 4 - phase;
    250         if ( nib >= 10 )
    251           break;
    252 
    253         exponent = exponent * 10 + nib;
    254 
    255         /* Arbitrarily limit exponent. */
    256         if ( exponent > 1000 )
    257           goto Exit;
    258       }
    259 
    260       if ( exponent_sign )
    261         exponent = -exponent;
    262     }
    263 
    264     /* We don't check `power_ten' and `exponent_add'. */
    265     exponent += power_ten + exponent_add;
    266 
    267     if ( scaling )
    268     {
    269       /* Only use `fraction_length'. */
    270       fraction_length += integer_length;
    271       exponent        += integer_length;
    272 
    273       if ( fraction_length <= 5 )
    274       {
    275         if ( number > 0x7FFFL )
    276         {
    277           result   = FT_DivFix( number, 10 );
    278           *scaling = exponent - fraction_length + 1;
    279         }
    280         else
    281         {
    282           if ( exponent > 0 )
    283           {
    284             FT_Long  new_fraction_length, shift;
    285 
    286 
    287             /* Make `scaling' as small as possible. */
    288             new_fraction_length = FT_MIN( exponent, 5 );
    289             exponent           -= new_fraction_length;
    290             shift               = new_fraction_length - fraction_length;
    291 
    292             number *= power_tens[shift];
    293             if ( number > 0x7FFFL )
    294             {
    295               number   /= 10;
    296               exponent += 1;
    297             }
    298           }
    299           else
    300             exponent -= fraction_length;
    301 
    302           result   = number << 16;
    303           *scaling = exponent;
    304         }
    305       }
    306       else
    307       {
    308         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
    309         {
    310           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
    311           *scaling = exponent - 4;
    312         }
    313         else
    314         {
    315           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
    316           *scaling = exponent - 5;
    317         }
    318       }
    319     }
    320     else
    321     {
    322       integer_length  += exponent;
    323       fraction_length -= exponent;
    324 
    325       /* Check for overflow and underflow. */
    326       if ( FT_ABS( integer_length ) > 5 )
    327         goto Exit;
    328 
    329       /* Remove non-significant digits. */
    330       if ( integer_length < 0 )
    331       {
    332         number          /= power_tens[-integer_length];
    333         fraction_length += integer_length;
    334       }
    335 
    336       /* this can only happen if exponent was non-zero */
    337       if ( fraction_length == 10 )
    338       {
    339         number          /= 10;
    340         fraction_length -= 1;
    341       }
    342 
    343       /* Convert into 16.16 format. */
    344       if ( fraction_length > 0 )
    345       {
    346         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
    347           goto Exit;
    348 
    349         result = FT_DivFix( number, power_tens[fraction_length] );
    350       }
    351       else
    352       {
    353         number *= power_tens[-fraction_length];
    354 
    355         if ( number > 0x7FFFL )
    356           goto Exit;
    357 
    358         result = number << 16;
    359       }
    360     }
    361 
    362     if ( sign )
    363       result = -result;
    364 
    365   Exit:
    366     return result;
    367   }
    368 
    369 
    370   /* read a number, either integer or real */
    371   static FT_Long
    372   cff_parse_num( FT_Byte**  d )
    373   {
    374     return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
    375                      :   cff_parse_integer( d[0], d[1] );
    376   }
    377 
    378 
    379   /* read a floating point number, either integer or real */
    380   static FT_Fixed
    381   cff_parse_fixed( FT_Byte**  d )
    382   {
    383     return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
    384                      : cff_parse_integer( d[0], d[1] ) << 16;
    385   }
    386 
    387 
    388   /* read a floating point number, either integer or real, */
    389   /* but return `10^scaling' times the number read in      */
    390   static FT_Fixed
    391   cff_parse_fixed_scaled( FT_Byte**  d,
    392                           FT_Long    scaling )
    393   {
    394     return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
    395                      : ( cff_parse_integer( d[0], d[1] ) *
    396                            power_tens[scaling] ) << 16;
    397   }
    398 
    399 
    400   /* read a floating point number, either integer or real,     */
    401   /* and return it as precise as possible -- `scaling' returns */
    402   /* the scaling factor (as a power of 10)                     */
    403   static FT_Fixed
    404   cff_parse_fixed_dynamic( FT_Byte**  d,
    405                            FT_Long*   scaling )
    406   {
    407     FT_ASSERT( scaling );
    408 
    409     if ( **d == 30 )
    410       return cff_parse_real( d[0], d[1], 0, scaling );
    411     else
    412     {
    413       FT_Long  number;
    414       FT_Int   integer_length;
    415 
    416 
    417       number = cff_parse_integer( d[0], d[1] );
    418 
    419       if ( number > 0x7FFFL )
    420       {
    421         for ( integer_length = 5; integer_length < 10; integer_length++ )
    422           if ( number < power_tens[integer_length] )
    423             break;
    424 
    425         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
    426         {
    427           *scaling = integer_length - 4;
    428           return FT_DivFix( number, power_tens[integer_length - 4] );
    429         }
    430         else
    431         {
    432           *scaling = integer_length - 5;
    433           return FT_DivFix( number, power_tens[integer_length - 5] );
    434         }
    435       }
    436       else
    437       {
    438         *scaling = 0;
    439         return number << 16;
    440       }
    441     }
    442   }
    443 
    444 
    445   static FT_Error
    446   cff_parse_font_matrix( CFF_Parser  parser )
    447   {
    448     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
    449     FT_Matrix*       matrix = &dict->font_matrix;
    450     FT_Vector*       offset = &dict->font_offset;
    451     FT_ULong*        upm    = &dict->units_per_em;
    452     FT_Byte**        data   = parser->stack;
    453     FT_Error         error  = CFF_Err_Stack_Underflow;
    454 
    455 
    456     if ( parser->top >= parser->stack + 6 )
    457     {
    458       FT_Long  scaling;
    459 
    460 
    461       error = CFF_Err_Ok;
    462 
    463       /* We expect a well-formed font matrix, this is, the matrix elements */
    464       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
    465       /* loss of precision, we use the magnitude of element `xx' to scale  */
    466       /* all other elements.  The scaling factor is then contained in the  */
    467       /* `units_per_em' value.                                             */
    468 
    469       matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
    470 
    471       scaling = -scaling;
    472 
    473       if ( scaling < 0 || scaling > 9 )
    474       {
    475         /* Return default matrix in case of unlikely values. */
    476 
    477         FT_TRACE1(( "cff_parse_font_matrix:"
    478                     " strange scaling value for xx element (%d),\n"
    479                     "                      "
    480                     " using default matrix\n", scaling ));
    481 
    482         matrix->xx = 0x10000L;
    483         matrix->yx = 0;
    484         matrix->xy = 0;
    485         matrix->yy = 0x10000L;
    486         offset->x  = 0;
    487         offset->y  = 0;
    488         *upm       = 1;
    489 
    490         goto Exit;
    491       }
    492 
    493       matrix->yx = cff_parse_fixed_scaled( data++, scaling );
    494       matrix->xy = cff_parse_fixed_scaled( data++, scaling );
    495       matrix->yy = cff_parse_fixed_scaled( data++, scaling );
    496       offset->x  = cff_parse_fixed_scaled( data++, scaling );
    497       offset->y  = cff_parse_fixed_scaled( data,   scaling );
    498 
    499       *upm = power_tens[scaling];
    500 
    501       FT_TRACE4(( " font matrix: [%f %f %f %f]\n",
    502                   (double)matrix->xx / *upm / 65536,
    503                   (double)matrix->xy / *upm / 65536,
    504                   (double)matrix->yx / *upm / 65536,
    505                   (double)matrix->yy / *upm / 65536 ));
    506     }
    507 
    508   Exit:
    509     return error;
    510   }
    511 
    512 
    513   static FT_Error
    514   cff_parse_font_bbox( CFF_Parser  parser )
    515   {
    516     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    517     FT_BBox*         bbox = &dict->font_bbox;
    518     FT_Byte**        data = parser->stack;
    519     FT_Error         error;
    520 
    521 
    522     error = CFF_Err_Stack_Underflow;
    523 
    524     if ( parser->top >= parser->stack + 4 )
    525     {
    526       bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
    527       bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
    528       bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
    529       bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
    530       error = CFF_Err_Ok;
    531 
    532       FT_TRACE4(( " bbox: [%d %d %d %d]\n",
    533                   bbox->xMin / 65536,
    534                   bbox->yMin / 65536,
    535                   bbox->xMax / 65536,
    536                   bbox->yMax / 65536 ));
    537     }
    538 
    539     return error;
    540   }
    541 
    542 
    543   static FT_Error
    544   cff_parse_private_dict( CFF_Parser  parser )
    545   {
    546     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    547     FT_Byte**        data = parser->stack;
    548     FT_Error         error;
    549 
    550 
    551     error = CFF_Err_Stack_Underflow;
    552 
    553     if ( parser->top >= parser->stack + 2 )
    554     {
    555       dict->private_size   = cff_parse_num( data++ );
    556       dict->private_offset = cff_parse_num( data   );
    557       error = CFF_Err_Ok;
    558     }
    559 
    560     return error;
    561   }
    562 
    563 
    564   static FT_Error
    565   cff_parse_cid_ros( CFF_Parser  parser )
    566   {
    567     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    568     FT_Byte**        data = parser->stack;
    569     FT_Error         error;
    570 
    571 
    572     error = CFF_Err_Stack_Underflow;
    573 
    574     if ( parser->top >= parser->stack + 3 )
    575     {
    576       dict->cid_registry   = (FT_UInt)cff_parse_num( data++ );
    577       dict->cid_ordering   = (FT_UInt)cff_parse_num( data++ );
    578       if ( **data == 30 )
    579         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
    580       dict->cid_supplement = cff_parse_num( data );
    581       if ( dict->cid_supplement < 0 )
    582         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
    583                    dict->cid_supplement ));
    584       error = CFF_Err_Ok;
    585 
    586       FT_TRACE4(( " ROS: registry sid %d, ordering sid %d, supplement %d\n",
    587                   dict->cid_registry,
    588                   dict->cid_ordering,
    589                   dict->cid_supplement ));
    590     }
    591 
    592     return error;
    593   }
    594 
    595 
    596 #define CFF_FIELD_NUM( code, name ) \
    597           CFF_FIELD( code, name, cff_kind_num )
    598 #define CFF_FIELD_FIXED( code, name ) \
    599           CFF_FIELD( code, name, cff_kind_fixed )
    600 #define CFF_FIELD_FIXED_1000( code, name ) \
    601           CFF_FIELD( code, name, cff_kind_fixed_thousand )
    602 #define CFF_FIELD_STRING( code, name ) \
    603           CFF_FIELD( code, name, cff_kind_string )
    604 #define CFF_FIELD_BOOL( code, name ) \
    605           CFF_FIELD( code, name, cff_kind_bool )
    606 #define CFF_FIELD_DELTA( code, name, max ) \
    607           CFF_FIELD( code, name, cff_kind_delta )
    608 
    609 #define CFFCODE_TOPDICT  0x1000
    610 #define CFFCODE_PRIVATE  0x2000
    611 
    612 #ifndef FT_CONFIG_OPTION_PIC
    613 
    614 #define CFF_FIELD_CALLBACK( code, name ) \
    615           {                              \
    616             cff_kind_callback,           \
    617             code | CFFCODE,              \
    618             0, 0,                        \
    619             cff_parse_ ## name,          \
    620             0, 0                         \
    621           },
    622 
    623 #undef  CFF_FIELD
    624 #define CFF_FIELD( code, name, kind ) \
    625           {                          \
    626             kind,                    \
    627             code | CFFCODE,          \
    628             FT_FIELD_OFFSET( name ), \
    629             FT_FIELD_SIZE( name ),   \
    630             0, 0, 0                  \
    631           },
    632 
    633 #undef  CFF_FIELD_DELTA
    634 #define CFF_FIELD_DELTA( code, name, max ) \
    635         {                                  \
    636           cff_kind_delta,                  \
    637           code | CFFCODE,                  \
    638           FT_FIELD_OFFSET( name ),         \
    639           FT_FIELD_SIZE_DELTA( name ),     \
    640           0,                               \
    641           max,                             \
    642           FT_FIELD_OFFSET( num_ ## name )  \
    643         },
    644 
    645   static const CFF_Field_Handler  cff_field_handlers[] =
    646   {
    647 
    648 #include "cfftoken.h"
    649 
    650     { 0, 0, 0, 0, 0, 0, 0 }
    651   };
    652 
    653 
    654 #else /* FT_CONFIG_OPTION_PIC */
    655 
    656   void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
    657   {
    658     FT_Memory memory = library->memory;
    659     if ( clazz )
    660       FT_FREE( clazz );
    661   }
    662 
    663   FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
    664   {
    665     CFF_Field_Handler*  clazz;
    666     FT_Error          error;
    667     FT_Memory memory = library->memory;
    668     int i=0;
    669 
    670 #undef CFF_FIELD
    671 #undef CFF_FIELD_DELTA
    672 #undef CFF_FIELD_CALLBACK
    673 #define CFF_FIELD_CALLBACK( code, name ) i++;
    674 #define CFF_FIELD( code, name, kind ) i++;
    675 #define CFF_FIELD_DELTA( code, name, max ) i++;
    676 
    677 #include "cfftoken.h"
    678     i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
    679 
    680     if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
    681       return error;
    682 
    683     i=0;
    684 #undef CFF_FIELD
    685 #undef CFF_FIELD_DELTA
    686 #undef CFF_FIELD_CALLBACK
    687 
    688 #define CFF_FIELD_CALLBACK( code_, name_ )                                   \
    689     clazz[i].kind = cff_kind_callback;                                       \
    690     clazz[i].code = code_ | CFFCODE;                                         \
    691     clazz[i].offset = 0;                                                     \
    692     clazz[i].size = 0;                                                       \
    693     clazz[i].reader = cff_parse_ ## name_;                                   \
    694     clazz[i].array_max = 0;                                                  \
    695     clazz[i].count_offset = 0;                                               \
    696     i++;
    697 
    698 #undef  CFF_FIELD
    699 #define CFF_FIELD( code_, name_, kind_ )                                     \
    700     clazz[i].kind = kind_;                                                   \
    701     clazz[i].code = code_ | CFFCODE;                                         \
    702     clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
    703     clazz[i].size = FT_FIELD_SIZE( name_ );                                  \
    704     clazz[i].reader = 0;                                                     \
    705     clazz[i].array_max = 0;                                                  \
    706     clazz[i].count_offset = 0;                                               \
    707     i++;                                                                     \
    708 
    709 #undef  CFF_FIELD_DELTA
    710 #define CFF_FIELD_DELTA( code_, name_, max_ )                                \
    711     clazz[i].kind = cff_kind_delta;                                          \
    712     clazz[i].code = code_ | CFFCODE;                                         \
    713     clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
    714     clazz[i].size = FT_FIELD_SIZE_DELTA( name_ );                            \
    715     clazz[i].reader = 0;                                                     \
    716     clazz[i].array_max = max_;                                               \
    717     clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ );                \
    718     i++;
    719 
    720 #include "cfftoken.h"
    721 
    722     clazz[i].kind = 0;
    723     clazz[i].code = 0;
    724     clazz[i].offset = 0;
    725     clazz[i].size = 0;
    726     clazz[i].reader = 0;
    727     clazz[i].array_max = 0;
    728     clazz[i].count_offset = 0;
    729 
    730     *output_class = clazz;
    731     return CFF_Err_Ok;
    732   }
    733 
    734 
    735 #endif /* FT_CONFIG_OPTION_PIC */
    736 
    737 
    738   FT_LOCAL_DEF( FT_Error )
    739   cff_parser_run( CFF_Parser  parser,
    740                   FT_Byte*    start,
    741                   FT_Byte*    limit )
    742   {
    743     FT_Byte*    p       = start;
    744     FT_Error    error   = CFF_Err_Ok;
    745     FT_Library  library = parser->library;
    746     FT_UNUSED(library);
    747 
    748 
    749     parser->top    = parser->stack;
    750     parser->start  = start;
    751     parser->limit  = limit;
    752     parser->cursor = start;
    753 
    754     while ( p < limit )
    755     {
    756       FT_UInt  v = *p;
    757 
    758 
    759       if ( v >= 27 && v != 31 )
    760       {
    761         /* it's a number; we will push its position on the stack */
    762         if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
    763           goto Stack_Overflow;
    764 
    765         *parser->top ++ = p;
    766 
    767         /* now, skip it */
    768         if ( v == 30 )
    769         {
    770           /* skip real number */
    771           p++;
    772           for (;;)
    773           {
    774             /* An unterminated floating point number at the */
    775             /* end of a dictionary is invalid but harmless. */
    776             if ( p >= limit )
    777               goto Exit;
    778             v = p[0] >> 4;
    779             if ( v == 15 )
    780               break;
    781             v = p[0] & 0xF;
    782             if ( v == 15 )
    783               break;
    784             p++;
    785           }
    786         }
    787         else if ( v == 28 )
    788           p += 2;
    789         else if ( v == 29 )
    790           p += 4;
    791         else if ( v > 246 )
    792           p += 1;
    793       }
    794       else
    795       {
    796         /* This is not a number, hence it's an operator.  Compute its code */
    797         /* and look for it in our current list.                            */
    798 
    799         FT_UInt                   code;
    800         FT_UInt                   num_args = (FT_UInt)
    801                                              ( parser->top - parser->stack );
    802         const CFF_Field_Handler*  field;
    803 
    804 
    805         *parser->top = p;
    806         code = v;
    807         if ( v == 12 )
    808         {
    809           /* two byte operator */
    810           p++;
    811           if ( p >= limit )
    812             goto Syntax_Error;
    813 
    814           code = 0x100 | p[0];
    815         }
    816         code = code | parser->object_code;
    817 
    818         for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
    819         {
    820           if ( field->code == (FT_Int)code )
    821           {
    822             /* we found our field's handler; read it */
    823             FT_Long   val;
    824             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
    825 
    826 
    827             /* check that we have enough arguments -- except for */
    828             /* delta encoded arrays, which can be empty          */
    829             if ( field->kind != cff_kind_delta && num_args < 1 )
    830               goto Stack_Underflow;
    831 
    832             switch ( field->kind )
    833             {
    834             case cff_kind_bool:
    835             case cff_kind_string:
    836             case cff_kind_num:
    837               val = cff_parse_num( parser->stack );
    838               goto Store_Number;
    839 
    840             case cff_kind_fixed:
    841               val = cff_parse_fixed( parser->stack );
    842               goto Store_Number;
    843 
    844             case cff_kind_fixed_thousand:
    845               val = cff_parse_fixed_scaled( parser->stack, 3 );
    846 
    847             Store_Number:
    848               switch ( field->size )
    849               {
    850               case (8 / FT_CHAR_BIT):
    851                 *(FT_Byte*)q = (FT_Byte)val;
    852                 break;
    853 
    854               case (16 / FT_CHAR_BIT):
    855                 *(FT_Short*)q = (FT_Short)val;
    856                 break;
    857 
    858               case (32 / FT_CHAR_BIT):
    859                 *(FT_Int32*)q = (FT_Int)val;
    860                 break;
    861 
    862               default:  /* for 64-bit systems */
    863                 *(FT_Long*)q = val;
    864               }
    865               break;
    866 
    867             case cff_kind_delta:
    868               {
    869                 FT_Byte*   qcount = (FT_Byte*)parser->object +
    870                                       field->count_offset;
    871 
    872                 FT_Byte**  data = parser->stack;
    873 
    874 
    875                 if ( num_args > field->array_max )
    876                   num_args = field->array_max;
    877 
    878                 /* store count */
    879                 *qcount = (FT_Byte)num_args;
    880 
    881                 val = 0;
    882                 while ( num_args > 0 )
    883                 {
    884                   val += cff_parse_num( data++ );
    885                   switch ( field->size )
    886                   {
    887                   case (8 / FT_CHAR_BIT):
    888                     *(FT_Byte*)q = (FT_Byte)val;
    889                     break;
    890 
    891                   case (16 / FT_CHAR_BIT):
    892                     *(FT_Short*)q = (FT_Short)val;
    893                     break;
    894 
    895                   case (32 / FT_CHAR_BIT):
    896                     *(FT_Int32*)q = (FT_Int)val;
    897                     break;
    898 
    899                   default:  /* for 64-bit systems */
    900                     *(FT_Long*)q = val;
    901                   }
    902 
    903                   q += field->size;
    904                   num_args--;
    905                 }
    906               }
    907               break;
    908 
    909             default:  /* callback */
    910               error = field->reader( parser );
    911               if ( error )
    912                 goto Exit;
    913             }
    914             goto Found;
    915           }
    916         }
    917 
    918         /* this is an unknown operator, or it is unsupported; */
    919         /* we will ignore it for now.                         */
    920 
    921       Found:
    922         /* clear stack */
    923         parser->top = parser->stack;
    924       }
    925       p++;
    926     }
    927 
    928   Exit:
    929     return error;
    930 
    931   Stack_Overflow:
    932     error = CFF_Err_Invalid_Argument;
    933     goto Exit;
    934 
    935   Stack_Underflow:
    936     error = CFF_Err_Invalid_Argument;
    937     goto Exit;
    938 
    939   Syntax_Error:
    940     error = CFF_Err_Invalid_Argument;
    941     goto Exit;
    942   }
    943 
    944 
    945 /* END */
    946