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