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-2014 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_UShort)p[0] << 8 ) | p[1] );
     69     }
     70     else if ( v == 29 )
     71     {
     72       if ( p + 4 > limit )
     73         goto Bad;
     74 
     75       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
     76                        ( (FT_ULong)p[1] << 16 ) |
     77                        ( (FT_ULong)p[2] <<  8 ) |
     78                          (FT_ULong)p[3]         );
     79     }
     80     else if ( v < 247 )
     81     {
     82       val = v - 139;
     83     }
     84     else if ( v < 251 )
     85     {
     86       if ( p + 1 > limit )
     87         goto Bad;
     88 
     89       val = ( v - 247 ) * 256 + p[0] + 108;
     90     }
     91     else
     92     {
     93       if ( p + 1 > limit )
     94         goto Bad;
     95 
     96       val = -( v - 251 ) * 256 - p[0] - 108;
     97     }
     98 
     99   Exit:
    100     return val;
    101 
    102   Bad:
    103     val = 0;
    104     FT_TRACE4(( "!!!END OF DATA:!!!" ));
    105     goto Exit;
    106   }
    107 
    108 
    109   static const FT_Long power_tens[] =
    110   {
    111     1L,
    112     10L,
    113     100L,
    114     1000L,
    115     10000L,
    116     100000L,
    117     1000000L,
    118     10000000L,
    119     100000000L,
    120     1000000000L
    121   };
    122 
    123 
    124   /* read a real */
    125   static FT_Fixed
    126   cff_parse_real( FT_Byte*  start,
    127                   FT_Byte*  limit,
    128                   FT_Long   power_ten,
    129                   FT_Long*  scaling )
    130   {
    131     FT_Byte*  p = start;
    132     FT_UInt   nib;
    133     FT_UInt   phase;
    134 
    135     FT_Long   result, number, exponent;
    136     FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
    137     FT_Long   exponent_add, integer_length, fraction_length;
    138 
    139 
    140     if ( scaling )
    141       *scaling = 0;
    142 
    143     result = 0;
    144 
    145     number   = 0;
    146     exponent = 0;
    147 
    148     exponent_add    = 0;
    149     integer_length  = 0;
    150     fraction_length = 0;
    151 
    152     /* First of all, read the integer part. */
    153     phase = 4;
    154 
    155     for (;;)
    156     {
    157       /* If we entered this iteration with phase == 4, we need to */
    158       /* read a new byte.  This also skips past the initial 0x1E. */
    159       if ( phase )
    160       {
    161         p++;
    162 
    163         /* Make sure we don't read past the end. */
    164         if ( p >= limit )
    165           goto Bad;
    166       }
    167 
    168       /* Get the nibble. */
    169       nib   = ( p[0] >> phase ) & 0xF;
    170       phase = 4 - phase;
    171 
    172       if ( nib == 0xE )
    173         sign = 1;
    174       else if ( nib > 9 )
    175         break;
    176       else
    177       {
    178         /* Increase exponent if we can't add the digit. */
    179         if ( number >= 0xCCCCCCCL )
    180           exponent_add++;
    181         /* Skip leading zeros. */
    182         else if ( nib || number )
    183         {
    184           integer_length++;
    185           number = number * 10 + nib;
    186         }
    187       }
    188     }
    189 
    190     /* Read fraction part, if any. */
    191     if ( nib == 0xa )
    192       for (;;)
    193       {
    194         /* If we entered this iteration with phase == 4, we need */
    195         /* to read a new byte.                                   */
    196         if ( phase )
    197         {
    198           p++;
    199 
    200           /* Make sure we don't read past the end. */
    201           if ( p >= limit )
    202             goto Bad;
    203         }
    204 
    205         /* Get the nibble. */
    206         nib   = ( p[0] >> phase ) & 0xF;
    207         phase = 4 - phase;
    208         if ( nib >= 10 )
    209           break;
    210 
    211         /* Skip leading zeros if possible. */
    212         if ( !nib && !number )
    213           exponent_add--;
    214         /* Only add digit if we don't overflow. */
    215         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
    216         {
    217           fraction_length++;
    218           number = number * 10 + nib;
    219         }
    220       }
    221 
    222     /* Read exponent, if any. */
    223     if ( nib == 12 )
    224     {
    225       exponent_sign = 1;
    226       nib           = 11;
    227     }
    228 
    229     if ( nib == 11 )
    230     {
    231       for (;;)
    232       {
    233         /* If we entered this iteration with phase == 4, */
    234         /* we need to read a new byte.                   */
    235         if ( phase )
    236         {
    237           p++;
    238 
    239           /* Make sure we don't read past the end. */
    240           if ( p >= limit )
    241             goto Bad;
    242         }
    243 
    244         /* Get the nibble. */
    245         nib   = ( p[0] >> phase ) & 0xF;
    246         phase = 4 - phase;
    247         if ( nib >= 10 )
    248           break;
    249 
    250         /* Arbitrarily limit exponent. */
    251         if ( exponent > 1000 )
    252           have_overflow = 1;
    253         else
    254           exponent = exponent * 10 + nib;
    255       }
    256 
    257       if ( exponent_sign )
    258         exponent = -exponent;
    259     }
    260 
    261     if ( !number )
    262       goto Exit;
    263 
    264     if ( have_overflow )
    265     {
    266       if ( exponent_sign )
    267         goto Underflow;
    268       else
    269         goto Overflow;
    270     }
    271 
    272     /* We don't check `power_ten' and `exponent_add'. */
    273     exponent += power_ten + exponent_add;
    274 
    275     if ( scaling )
    276     {
    277       /* Only use `fraction_length'. */
    278       fraction_length += integer_length;
    279       exponent        += integer_length;
    280 
    281       if ( fraction_length <= 5 )
    282       {
    283         if ( number > 0x7FFFL )
    284         {
    285           result   = FT_DivFix( number, 10 );
    286           *scaling = exponent - fraction_length + 1;
    287         }
    288         else
    289         {
    290           if ( exponent > 0 )
    291           {
    292             FT_Long  new_fraction_length, shift;
    293 
    294 
    295             /* Make `scaling' as small as possible. */
    296             new_fraction_length = FT_MIN( exponent, 5 );
    297             shift               = new_fraction_length - fraction_length;
    298 
    299             if ( shift > 0 )
    300             {
    301               exponent -= new_fraction_length;
    302               number   *= power_tens[shift];
    303               if ( number > 0x7FFFL )
    304               {
    305                 number   /= 10;
    306                 exponent += 1;
    307               }
    308             }
    309             else
    310               exponent -= fraction_length;
    311           }
    312           else
    313             exponent -= fraction_length;
    314 
    315           result   = (FT_Long)( (FT_ULong)number << 16 );
    316           *scaling = exponent;
    317         }
    318       }
    319       else
    320       {
    321         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
    322         {
    323           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
    324           *scaling = exponent - 4;
    325         }
    326         else
    327         {
    328           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
    329           *scaling = exponent - 5;
    330         }
    331       }
    332     }
    333     else
    334     {
    335       integer_length  += exponent;
    336       fraction_length -= exponent;
    337 
    338       if ( integer_length > 5 )
    339         goto Overflow;
    340       if ( integer_length < -5 )
    341         goto Underflow;
    342 
    343       /* Remove non-significant digits. */
    344       if ( integer_length < 0 )
    345       {
    346         number          /= power_tens[-integer_length];
    347         fraction_length += integer_length;
    348       }
    349 
    350       /* this can only happen if exponent was non-zero */
    351       if ( fraction_length == 10 )
    352       {
    353         number          /= 10;
    354         fraction_length -= 1;
    355       }
    356 
    357       /* Convert into 16.16 format. */
    358       if ( fraction_length > 0 )
    359       {
    360         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
    361           goto Exit;
    362 
    363         result = FT_DivFix( number, power_tens[fraction_length] );
    364       }
    365       else
    366       {
    367         number *= power_tens[-fraction_length];
    368 
    369         if ( number > 0x7FFFL )
    370           goto Overflow;
    371 
    372         result = (FT_Long)( (FT_ULong)number << 16 );
    373       }
    374     }
    375 
    376   Exit:
    377     if ( sign )
    378       result = -result;
    379 
    380     return result;
    381 
    382   Overflow:
    383     result = 0x7FFFFFFFL;
    384     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
    385     goto Exit;
    386 
    387   Underflow:
    388     result = 0;
    389     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
    390     goto Exit;
    391 
    392   Bad:
    393     result = 0;
    394     FT_TRACE4(( "!!!END OF DATA:!!!" ));
    395     goto Exit;
    396   }
    397 
    398 
    399   /* read a number, either integer or real */
    400   static FT_Long
    401   cff_parse_num( FT_Byte**  d )
    402   {
    403     return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
    404                      :   cff_parse_integer( d[0], d[1] );
    405   }
    406 
    407 
    408   /* read a floating point number, either integer or real */
    409   static FT_Fixed
    410   do_fixed( FT_Byte**  d,
    411             FT_Long    scaling )
    412   {
    413     if ( **d == 30 )
    414       return cff_parse_real( d[0], d[1], scaling, NULL );
    415     else
    416     {
    417       FT_Long  val = cff_parse_integer( d[0], d[1] );
    418 
    419 
    420       if ( scaling )
    421         val *= power_tens[scaling];
    422 
    423       if ( val > 0x7FFF )
    424       {
    425         val = 0x7FFFFFFFL;
    426         goto Overflow;
    427       }
    428       else if ( val < -0x7FFF )
    429       {
    430         val = -0x7FFFFFFFL;
    431         goto Overflow;
    432       }
    433 
    434       return (FT_Long)( (FT_ULong)val << 16 );
    435 
    436     Overflow:
    437       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
    438       return val;
    439     }
    440   }
    441 
    442 
    443   /* read a floating point number, either integer or real */
    444   static FT_Fixed
    445   cff_parse_fixed( FT_Byte**  d )
    446   {
    447     return do_fixed( d, 0 );
    448   }
    449 
    450 
    451   /* read a floating point number, either integer or real, */
    452   /* but return `10^scaling' times the number read in      */
    453   static FT_Fixed
    454   cff_parse_fixed_scaled( FT_Byte**  d,
    455                           FT_Long    scaling )
    456   {
    457     return do_fixed( d, scaling );
    458   }
    459 
    460 
    461   /* read a floating point number, either integer or real,     */
    462   /* and return it as precise as possible -- `scaling' returns */
    463   /* the scaling factor (as a power of 10)                     */
    464   static FT_Fixed
    465   cff_parse_fixed_dynamic( FT_Byte**  d,
    466                            FT_Long*   scaling )
    467   {
    468     FT_ASSERT( scaling );
    469 
    470     if ( **d == 30 )
    471       return cff_parse_real( d[0], d[1], 0, scaling );
    472     else
    473     {
    474       FT_Long  number;
    475       FT_Int   integer_length;
    476 
    477 
    478       number = cff_parse_integer( d[0], d[1] );
    479 
    480       if ( number > 0x7FFFL )
    481       {
    482         for ( integer_length = 5; integer_length < 10; integer_length++ )
    483           if ( number < power_tens[integer_length] )
    484             break;
    485 
    486         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
    487         {
    488           *scaling = integer_length - 4;
    489           return FT_DivFix( number, power_tens[integer_length - 4] );
    490         }
    491         else
    492         {
    493           *scaling = integer_length - 5;
    494           return FT_DivFix( number, power_tens[integer_length - 5] );
    495         }
    496       }
    497       else
    498       {
    499         *scaling = 0;
    500         return (FT_Long)( (FT_ULong)number << 16 );
    501       }
    502     }
    503   }
    504 
    505 
    506   static FT_Error
    507   cff_parse_font_matrix( CFF_Parser  parser )
    508   {
    509     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
    510     FT_Matrix*       matrix = &dict->font_matrix;
    511     FT_Vector*       offset = &dict->font_offset;
    512     FT_ULong*        upm    = &dict->units_per_em;
    513     FT_Byte**        data   = parser->stack;
    514     FT_Error         error  = FT_ERR( Stack_Underflow );
    515 
    516 
    517     if ( parser->top >= parser->stack + 6 )
    518     {
    519       FT_Long  scaling;
    520 
    521 
    522       error = FT_Err_Ok;
    523 
    524       dict->has_font_matrix = TRUE;
    525 
    526       /* We expect a well-formed font matrix, this is, the matrix elements */
    527       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
    528       /* loss of precision, we use the magnitude of element `xx' to scale  */
    529       /* all other elements.  The scaling factor is then contained in the  */
    530       /* `units_per_em' value.                                             */
    531 
    532       matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
    533 
    534       scaling = -scaling;
    535 
    536       if ( scaling < 0 || scaling > 9 )
    537       {
    538         /* Return default matrix in case of unlikely values. */
    539 
    540         FT_TRACE1(( "cff_parse_font_matrix:"
    541                     " strange scaling value for xx element (%d),\n"
    542                     "                      "
    543                     " using default matrix\n", scaling ));
    544 
    545         matrix->xx = 0x10000L;
    546         matrix->yx = 0;
    547         matrix->xy = 0;
    548         matrix->yy = 0x10000L;
    549         offset->x  = 0;
    550         offset->y  = 0;
    551         *upm       = 1;
    552 
    553         goto Exit;
    554       }
    555 
    556       matrix->yx = cff_parse_fixed_scaled( data++, scaling );
    557       matrix->xy = cff_parse_fixed_scaled( data++, scaling );
    558       matrix->yy = cff_parse_fixed_scaled( data++, scaling );
    559       offset->x  = cff_parse_fixed_scaled( data++, scaling );
    560       offset->y  = cff_parse_fixed_scaled( data,   scaling );
    561 
    562       *upm = power_tens[scaling];
    563 
    564       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
    565                   (double)matrix->xx / *upm / 65536,
    566                   (double)matrix->xy / *upm / 65536,
    567                   (double)matrix->yx / *upm / 65536,
    568                   (double)matrix->yy / *upm / 65536,
    569                   (double)offset->x  / *upm / 65536,
    570                   (double)offset->y  / *upm / 65536 ));
    571     }
    572 
    573   Exit:
    574     return error;
    575   }
    576 
    577 
    578   static FT_Error
    579   cff_parse_font_bbox( CFF_Parser  parser )
    580   {
    581     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    582     FT_BBox*         bbox = &dict->font_bbox;
    583     FT_Byte**        data = parser->stack;
    584     FT_Error         error;
    585 
    586 
    587     error = FT_ERR( Stack_Underflow );
    588 
    589     if ( parser->top >= parser->stack + 4 )
    590     {
    591       bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
    592       bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
    593       bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
    594       bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
    595       error = FT_Err_Ok;
    596 
    597       FT_TRACE4(( " [%d %d %d %d]\n",
    598                   bbox->xMin / 65536,
    599                   bbox->yMin / 65536,
    600                   bbox->xMax / 65536,
    601                   bbox->yMax / 65536 ));
    602     }
    603 
    604     return error;
    605   }
    606 
    607 
    608   static FT_Error
    609   cff_parse_private_dict( CFF_Parser  parser )
    610   {
    611     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    612     FT_Byte**        data = parser->stack;
    613     FT_Error         error;
    614 
    615 
    616     error = FT_ERR( Stack_Underflow );
    617 
    618     if ( parser->top >= parser->stack + 2 )
    619     {
    620       dict->private_size   = cff_parse_num( data++ );
    621       dict->private_offset = cff_parse_num( data   );
    622       FT_TRACE4(( " %lu %lu\n",
    623                   dict->private_size, dict->private_offset ));
    624 
    625       error = FT_Err_Ok;
    626     }
    627 
    628     return error;
    629   }
    630 
    631 
    632   static FT_Error
    633   cff_parse_cid_ros( CFF_Parser  parser )
    634   {
    635     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    636     FT_Byte**        data = parser->stack;
    637     FT_Error         error;
    638 
    639 
    640     error = FT_ERR( Stack_Underflow );
    641 
    642     if ( parser->top >= parser->stack + 3 )
    643     {
    644       dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
    645       dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
    646       if ( **data == 30 )
    647         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
    648       dict->cid_supplement = cff_parse_num( data );
    649       if ( dict->cid_supplement < 0 )
    650         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
    651                    dict->cid_supplement ));
    652       error = FT_Err_Ok;
    653 
    654       FT_TRACE4(( " %d %d %d\n",
    655                   dict->cid_registry,
    656                   dict->cid_ordering,
    657                   dict->cid_supplement ));
    658     }
    659 
    660     return error;
    661   }
    662 
    663 
    664 #define CFF_FIELD_NUM( code, name, id )             \
    665           CFF_FIELD( code, name, id, cff_kind_num )
    666 #define CFF_FIELD_FIXED( code, name, id )             \
    667           CFF_FIELD( code, name, id, cff_kind_fixed )
    668 #define CFF_FIELD_FIXED_1000( code, name, id )                 \
    669           CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
    670 #define CFF_FIELD_STRING( code, name, id )             \
    671           CFF_FIELD( code, name, id, cff_kind_string )
    672 #define CFF_FIELD_BOOL( code, name, id )             \
    673           CFF_FIELD( code, name, id, cff_kind_bool )
    674 
    675 #define CFFCODE_TOPDICT  0x1000
    676 #define CFFCODE_PRIVATE  0x2000
    677 
    678 
    679 #ifndef FT_CONFIG_OPTION_PIC
    680 
    681 
    682 #undef  CFF_FIELD
    683 #undef  CFF_FIELD_DELTA
    684 
    685 
    686 #ifndef FT_DEBUG_LEVEL_TRACE
    687 
    688 
    689 #define CFF_FIELD_CALLBACK( code, name, id ) \
    690           {                                  \
    691             cff_kind_callback,               \
    692             code | CFFCODE,                  \
    693             0, 0,                            \
    694             cff_parse_ ## name,              \
    695             0, 0                             \
    696           },
    697 
    698 #define CFF_FIELD( code, name, id, kind ) \
    699           {                               \
    700             kind,                         \
    701             code | CFFCODE,               \
    702             FT_FIELD_OFFSET( name ),      \
    703             FT_FIELD_SIZE( name ),        \
    704             0, 0, 0                       \
    705           },
    706 
    707 #define CFF_FIELD_DELTA( code, name, max, id ) \
    708           {                                    \
    709             cff_kind_delta,                    \
    710             code | CFFCODE,                    \
    711             FT_FIELD_OFFSET( name ),           \
    712             FT_FIELD_SIZE_DELTA( name ),       \
    713             0,                                 \
    714             max,                               \
    715             FT_FIELD_OFFSET( num_ ## name )    \
    716           },
    717 
    718   static const CFF_Field_Handler  cff_field_handlers[] =
    719   {
    720 
    721 #include "cfftoken.h"
    722 
    723     { 0, 0, 0, 0, 0, 0, 0 }
    724   };
    725 
    726 
    727 #else /* FT_DEBUG_LEVEL_TRACE */
    728 
    729 
    730 
    731 #define CFF_FIELD_CALLBACK( code, name, id ) \
    732           {                                  \
    733             cff_kind_callback,               \
    734             code | CFFCODE,                  \
    735             0, 0,                            \
    736             cff_parse_ ## name,              \
    737             0, 0,                            \
    738             id                               \
    739           },
    740 
    741 #define CFF_FIELD( code, name, id, kind ) \
    742           {                               \
    743             kind,                         \
    744             code | CFFCODE,               \
    745             FT_FIELD_OFFSET( name ),      \
    746             FT_FIELD_SIZE( name ),        \
    747             0, 0, 0,                      \
    748             id                            \
    749           },
    750 
    751 #define CFF_FIELD_DELTA( code, name, max, id ) \
    752           {                                    \
    753             cff_kind_delta,                    \
    754             code | CFFCODE,                    \
    755             FT_FIELD_OFFSET( name ),           \
    756             FT_FIELD_SIZE_DELTA( name ),       \
    757             0,                                 \
    758             max,                               \
    759             FT_FIELD_OFFSET( num_ ## name ),   \
    760             id                                 \
    761           },
    762 
    763   static const CFF_Field_Handler  cff_field_handlers[] =
    764   {
    765 
    766 #include "cfftoken.h"
    767 
    768     { 0, 0, 0, 0, 0, 0, 0, 0 }
    769   };
    770 
    771 
    772 #endif /* FT_DEBUG_LEVEL_TRACE */
    773 
    774 
    775 #else /* FT_CONFIG_OPTION_PIC */
    776 
    777 
    778   void
    779   FT_Destroy_Class_cff_field_handlers( FT_Library          library,
    780                                        CFF_Field_Handler*  clazz )
    781   {
    782     FT_Memory  memory = library->memory;
    783 
    784 
    785     if ( clazz )
    786       FT_FREE( clazz );
    787   }
    788 
    789 
    790   FT_Error
    791   FT_Create_Class_cff_field_handlers( FT_Library           library,
    792                                       CFF_Field_Handler**  output_class )
    793   {
    794     CFF_Field_Handler*  clazz  = NULL;
    795     FT_Error            error;
    796     FT_Memory           memory = library->memory;
    797 
    798     int  i = 0;
    799 
    800 
    801 #undef CFF_FIELD
    802 #define CFF_FIELD( code, name, id, kind ) i++;
    803 #undef CFF_FIELD_DELTA
    804 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
    805 #undef CFF_FIELD_CALLBACK
    806 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
    807 
    808 #include "cfftoken.h"
    809 
    810     i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
    811 
    812     if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
    813       return error;
    814 
    815     i = 0;
    816 
    817 
    818 #ifndef FT_DEBUG_LEVEL_TRACE
    819 
    820 
    821 #undef CFF_FIELD_CALLBACK
    822 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
    823           clazz[i].kind         = cff_kind_callback;   \
    824           clazz[i].code         = code_ | CFFCODE;     \
    825           clazz[i].offset       = 0;                   \
    826           clazz[i].size         = 0;                   \
    827           clazz[i].reader       = cff_parse_ ## name_; \
    828           clazz[i].array_max    = 0;                   \
    829           clazz[i].count_offset = 0;                   \
    830           i++;
    831 
    832 #undef  CFF_FIELD
    833 #define CFF_FIELD( code_, name_, id_, kind_ )               \
    834           clazz[i].kind         = kind_;                    \
    835           clazz[i].code         = code_ | CFFCODE;          \
    836           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
    837           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
    838           clazz[i].reader       = 0;                        \
    839           clazz[i].array_max    = 0;                        \
    840           clazz[i].count_offset = 0;                        \
    841           i++;                                              \
    842 
    843 #undef  CFF_FIELD_DELTA
    844 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
    845           clazz[i].kind         = cff_kind_delta;                   \
    846           clazz[i].code         = code_ | CFFCODE;                  \
    847           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
    848           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
    849           clazz[i].reader       = 0;                                \
    850           clazz[i].array_max    = max_;                             \
    851           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
    852           i++;
    853 
    854 #include "cfftoken.h"
    855 
    856     clazz[i].kind         = 0;
    857     clazz[i].code         = 0;
    858     clazz[i].offset       = 0;
    859     clazz[i].size         = 0;
    860     clazz[i].reader       = 0;
    861     clazz[i].array_max    = 0;
    862     clazz[i].count_offset = 0;
    863 
    864 
    865 #else /* FT_DEBUG_LEVEL_TRACE */
    866 
    867 
    868 #undef CFF_FIELD_CALLBACK
    869 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
    870           clazz[i].kind         = cff_kind_callback;   \
    871           clazz[i].code         = code_ | CFFCODE;     \
    872           clazz[i].offset       = 0;                   \
    873           clazz[i].size         = 0;                   \
    874           clazz[i].reader       = cff_parse_ ## name_; \
    875           clazz[i].array_max    = 0;                   \
    876           clazz[i].count_offset = 0;                   \
    877           clazz[i].id           = id_;                 \
    878           i++;
    879 
    880 #undef  CFF_FIELD
    881 #define CFF_FIELD( code_, name_, id_, kind_ )               \
    882           clazz[i].kind         = kind_;                    \
    883           clazz[i].code         = code_ | CFFCODE;          \
    884           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
    885           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
    886           clazz[i].reader       = 0;                        \
    887           clazz[i].array_max    = 0;                        \
    888           clazz[i].count_offset = 0;                        \
    889           clazz[i].id           = id_;                      \
    890           i++;                                              \
    891 
    892 #undef  CFF_FIELD_DELTA
    893 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
    894           clazz[i].kind         = cff_kind_delta;                   \
    895           clazz[i].code         = code_ | CFFCODE;                  \
    896           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
    897           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
    898           clazz[i].reader       = 0;                                \
    899           clazz[i].array_max    = max_;                             \
    900           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
    901           clazz[i].id           = id_;                              \
    902           i++;
    903 
    904 #include "cfftoken.h"
    905 
    906     clazz[i].kind         = 0;
    907     clazz[i].code         = 0;
    908     clazz[i].offset       = 0;
    909     clazz[i].size         = 0;
    910     clazz[i].reader       = 0;
    911     clazz[i].array_max    = 0;
    912     clazz[i].count_offset = 0;
    913     clazz[i].id           = 0;
    914 
    915 
    916 #endif /* FT_DEBUG_LEVEL_TRACE */
    917 
    918 
    919     *output_class = clazz;
    920 
    921     return FT_Err_Ok;
    922   }
    923 
    924 
    925 #endif /* FT_CONFIG_OPTION_PIC */
    926 
    927 
    928   FT_LOCAL_DEF( FT_Error )
    929   cff_parser_run( CFF_Parser  parser,
    930                   FT_Byte*    start,
    931                   FT_Byte*    limit )
    932   {
    933     FT_Byte*    p       = start;
    934     FT_Error    error   = FT_Err_Ok;
    935     FT_Library  library = parser->library;
    936     FT_UNUSED( library );
    937 
    938 
    939     parser->top    = parser->stack;
    940     parser->start  = start;
    941     parser->limit  = limit;
    942     parser->cursor = start;
    943 
    944     while ( p < limit )
    945     {
    946       FT_UInt  v = *p;
    947 
    948 
    949       if ( v >= 27 && v != 31 )
    950       {
    951         /* it's a number; we will push its position on the stack */
    952         if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
    953           goto Stack_Overflow;
    954 
    955         *parser->top ++ = p;
    956 
    957         /* now, skip it */
    958         if ( v == 30 )
    959         {
    960           /* skip real number */
    961           p++;
    962           for (;;)
    963           {
    964             /* An unterminated floating point number at the */
    965             /* end of a dictionary is invalid but harmless. */
    966             if ( p >= limit )
    967               goto Exit;
    968             v = p[0] >> 4;
    969             if ( v == 15 )
    970               break;
    971             v = p[0] & 0xF;
    972             if ( v == 15 )
    973               break;
    974             p++;
    975           }
    976         }
    977         else if ( v == 28 )
    978           p += 2;
    979         else if ( v == 29 )
    980           p += 4;
    981         else if ( v > 246 )
    982           p += 1;
    983       }
    984       else
    985       {
    986         /* This is not a number, hence it's an operator.  Compute its code */
    987         /* and look for it in our current list.                            */
    988 
    989         FT_UInt                   code;
    990         FT_UInt                   num_args = (FT_UInt)
    991                                              ( parser->top - parser->stack );
    992         const CFF_Field_Handler*  field;
    993 
    994 
    995         *parser->top = p;
    996         code = v;
    997         if ( v == 12 )
    998         {
    999           /* two byte operator */
   1000           p++;
   1001           if ( p >= limit )
   1002             goto Syntax_Error;
   1003 
   1004           code = 0x100 | p[0];
   1005         }
   1006         code = code | parser->object_code;
   1007 
   1008         for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
   1009         {
   1010           if ( field->code == (FT_Int)code )
   1011           {
   1012             /* we found our field's handler; read it */
   1013             FT_Long   val;
   1014             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
   1015 
   1016 
   1017 #ifdef FT_DEBUG_LEVEL_TRACE
   1018             FT_TRACE4(( "  %s", field->id ));
   1019 #endif
   1020 
   1021             /* check that we have enough arguments -- except for */
   1022             /* delta encoded arrays, which can be empty          */
   1023             if ( field->kind != cff_kind_delta && num_args < 1 )
   1024               goto Stack_Underflow;
   1025 
   1026             switch ( field->kind )
   1027             {
   1028             case cff_kind_bool:
   1029             case cff_kind_string:
   1030             case cff_kind_num:
   1031               val = cff_parse_num( parser->stack );
   1032               goto Store_Number;
   1033 
   1034             case cff_kind_fixed:
   1035               val = cff_parse_fixed( parser->stack );
   1036               goto Store_Number;
   1037 
   1038             case cff_kind_fixed_thousand:
   1039               val = cff_parse_fixed_scaled( parser->stack, 3 );
   1040 
   1041             Store_Number:
   1042               switch ( field->size )
   1043               {
   1044               case (8 / FT_CHAR_BIT):
   1045                 *(FT_Byte*)q = (FT_Byte)val;
   1046                 break;
   1047 
   1048               case (16 / FT_CHAR_BIT):
   1049                 *(FT_Short*)q = (FT_Short)val;
   1050                 break;
   1051 
   1052               case (32 / FT_CHAR_BIT):
   1053                 *(FT_Int32*)q = (FT_Int)val;
   1054                 break;
   1055 
   1056               default:  /* for 64-bit systems */
   1057                 *(FT_Long*)q = val;
   1058               }
   1059 
   1060 #ifdef FT_DEBUG_LEVEL_TRACE
   1061               switch ( field->kind )
   1062               {
   1063               case cff_kind_bool:
   1064                 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
   1065                 break;
   1066 
   1067               case cff_kind_string:
   1068                 FT_TRACE4(( " %ld (SID)\n", val ));
   1069                 break;
   1070 
   1071               case cff_kind_num:
   1072                 FT_TRACE4(( " %ld\n", val ));
   1073                 break;
   1074 
   1075               case cff_kind_fixed:
   1076                 FT_TRACE4(( " %f\n", (double)val / 65536 ));
   1077                 break;
   1078 
   1079               case cff_kind_fixed_thousand:
   1080                 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
   1081 
   1082               default:
   1083                 ; /* never reached */
   1084               }
   1085 #endif
   1086 
   1087               break;
   1088 
   1089             case cff_kind_delta:
   1090               {
   1091                 FT_Byte*   qcount = (FT_Byte*)parser->object +
   1092                                       field->count_offset;
   1093 
   1094                 FT_Byte**  data = parser->stack;
   1095 
   1096 
   1097                 if ( num_args > field->array_max )
   1098                   num_args = field->array_max;
   1099 
   1100                 FT_TRACE4(( " [" ));
   1101 
   1102                 /* store count */
   1103                 *qcount = (FT_Byte)num_args;
   1104 
   1105                 val = 0;
   1106                 while ( num_args > 0 )
   1107                 {
   1108                   val += cff_parse_num( data++ );
   1109                   switch ( field->size )
   1110                   {
   1111                   case (8 / FT_CHAR_BIT):
   1112                     *(FT_Byte*)q = (FT_Byte)val;
   1113                     break;
   1114 
   1115                   case (16 / FT_CHAR_BIT):
   1116                     *(FT_Short*)q = (FT_Short)val;
   1117                     break;
   1118 
   1119                   case (32 / FT_CHAR_BIT):
   1120                     *(FT_Int32*)q = (FT_Int)val;
   1121                     break;
   1122 
   1123                   default:  /* for 64-bit systems */
   1124                     *(FT_Long*)q = val;
   1125                   }
   1126 
   1127                   FT_TRACE4(( " %ld", val ));
   1128 
   1129                   q += field->size;
   1130                   num_args--;
   1131                 }
   1132 
   1133                 FT_TRACE4(( "]\n" ));
   1134               }
   1135               break;
   1136 
   1137             default:  /* callback */
   1138               error = field->reader( parser );
   1139               if ( error )
   1140                 goto Exit;
   1141             }
   1142             goto Found;
   1143           }
   1144         }
   1145 
   1146         /* this is an unknown operator, or it is unsupported; */
   1147         /* we will ignore it for now.                         */
   1148 
   1149       Found:
   1150         /* clear stack */
   1151         parser->top = parser->stack;
   1152       }
   1153       p++;
   1154     }
   1155 
   1156   Exit:
   1157     return error;
   1158 
   1159   Stack_Overflow:
   1160     error = FT_THROW( Invalid_Argument );
   1161     goto Exit;
   1162 
   1163   Stack_Underflow:
   1164     error = FT_THROW( Invalid_Argument );
   1165     goto Exit;
   1166 
   1167   Syntax_Error:
   1168     error = FT_THROW( Invalid_Argument );
   1169     goto Exit;
   1170   }
   1171 
   1172 
   1173 /* END */
   1174