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