Home | History | Annotate | Download | only in cff
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  cffparse.c                                                             */
      4 /*                                                                         */
      5 /*    CFF token stream parser (body)                                       */
      6 /*                                                                         */
      7 /*  Copyright 1996-2018 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 #include FT_INTERNAL_CALC_H
     24 #include FT_INTERNAL_POSTSCRIPT_AUX_H
     25 
     26 #include "cfferrs.h"
     27 #include "cffpic.h"
     28 #include "cffload.h"
     29 
     30 
     31   /*************************************************************************/
     32   /*                                                                       */
     33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     35   /* messages during execution.                                            */
     36   /*                                                                       */
     37 #undef  FT_COMPONENT
     38 #define FT_COMPONENT  trace_cffparse
     39 
     40 
     41   FT_LOCAL_DEF( FT_Error )
     42   cff_parser_init( CFF_Parser  parser,
     43                    FT_UInt     code,
     44                    void*       object,
     45                    FT_Library  library,
     46                    FT_UInt     stackSize,
     47                    FT_UShort   num_designs,
     48                    FT_UShort   num_axes )
     49   {
     50     FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
     51     FT_Error   error;                       /* for FT_NEW_ARRAY */
     52 
     53 
     54     FT_ZERO( parser );
     55 
     56 #if 0
     57     parser->top         = parser->stack;
     58 #endif
     59     parser->object_code = code;
     60     parser->object      = object;
     61     parser->library     = library;
     62     parser->num_designs = num_designs;
     63     parser->num_axes    = num_axes;
     64 
     65     /* allocate the stack buffer */
     66     if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
     67     {
     68       FT_FREE( parser->stack );
     69       goto Exit;
     70     }
     71 
     72     parser->stackSize = stackSize;
     73     parser->top       = parser->stack;    /* empty stack */
     74 
     75   Exit:
     76     return error;
     77   }
     78 
     79 
     80   FT_LOCAL_DEF( void )
     81   cff_parser_done( CFF_Parser  parser )
     82   {
     83     FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
     84 
     85 
     86     FT_FREE( parser->stack );
     87   }
     88 
     89 
     90   /* read an integer */
     91   static FT_Long
     92   cff_parse_integer( FT_Byte*  start,
     93                      FT_Byte*  limit )
     94   {
     95     FT_Byte*  p   = start;
     96     FT_Int    v   = *p++;
     97     FT_Long   val = 0;
     98 
     99 
    100     if ( v == 28 )
    101     {
    102       if ( p + 2 > limit )
    103         goto Bad;
    104 
    105       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
    106     }
    107     else if ( v == 29 )
    108     {
    109       if ( p + 4 > limit )
    110         goto Bad;
    111 
    112       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
    113                        ( (FT_ULong)p[1] << 16 ) |
    114                        ( (FT_ULong)p[2] <<  8 ) |
    115                          (FT_ULong)p[3]         );
    116     }
    117     else if ( v < 247 )
    118     {
    119       val = v - 139;
    120     }
    121     else if ( v < 251 )
    122     {
    123       if ( p + 1 > limit )
    124         goto Bad;
    125 
    126       val = ( v - 247 ) * 256 + p[0] + 108;
    127     }
    128     else
    129     {
    130       if ( p + 1 > limit )
    131         goto Bad;
    132 
    133       val = -( v - 251 ) * 256 - p[0] - 108;
    134     }
    135 
    136   Exit:
    137     return val;
    138 
    139   Bad:
    140     val = 0;
    141     FT_TRACE4(( "!!!END OF DATA:!!!" ));
    142     goto Exit;
    143   }
    144 
    145 
    146   static const FT_Long power_tens[] =
    147   {
    148     1L,
    149     10L,
    150     100L,
    151     1000L,
    152     10000L,
    153     100000L,
    154     1000000L,
    155     10000000L,
    156     100000000L,
    157     1000000000L
    158   };
    159 
    160   /* maximum values allowed for multiplying      */
    161   /* with the corresponding `power_tens' element */
    162   static const FT_Long power_ten_limits[] =
    163   {
    164     FT_LONG_MAX / 1L,
    165     FT_LONG_MAX / 10L,
    166     FT_LONG_MAX / 100L,
    167     FT_LONG_MAX / 1000L,
    168     FT_LONG_MAX / 10000L,
    169     FT_LONG_MAX / 100000L,
    170     FT_LONG_MAX / 1000000L,
    171     FT_LONG_MAX / 10000000L,
    172     FT_LONG_MAX / 100000000L,
    173     FT_LONG_MAX / 1000000000L,
    174   };
    175 
    176 
    177   /* read a real */
    178   static FT_Fixed
    179   cff_parse_real( FT_Byte*  start,
    180                   FT_Byte*  limit,
    181                   FT_Long   power_ten,
    182                   FT_Long*  scaling )
    183   {
    184     FT_Byte*  p = start;
    185     FT_Int    nib;
    186     FT_UInt   phase;
    187 
    188     FT_Long   result, number, exponent;
    189     FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
    190     FT_Long   exponent_add, integer_length, fraction_length;
    191 
    192 
    193     if ( scaling )
    194       *scaling = 0;
    195 
    196     result = 0;
    197 
    198     number   = 0;
    199     exponent = 0;
    200 
    201     exponent_add    = 0;
    202     integer_length  = 0;
    203     fraction_length = 0;
    204 
    205     /* First of all, read the integer part. */
    206     phase = 4;
    207 
    208     for (;;)
    209     {
    210       /* If we entered this iteration with phase == 4, we need to */
    211       /* read a new byte.  This also skips past the initial 0x1E. */
    212       if ( phase )
    213       {
    214         p++;
    215 
    216         /* Make sure we don't read past the end. */
    217         if ( p >= limit )
    218           goto Bad;
    219       }
    220 
    221       /* Get the nibble. */
    222       nib   = (FT_Int)( p[0] >> phase ) & 0xF;
    223       phase = 4 - phase;
    224 
    225       if ( nib == 0xE )
    226         sign = 1;
    227       else if ( nib > 9 )
    228         break;
    229       else
    230       {
    231         /* Increase exponent if we can't add the digit. */
    232         if ( number >= 0xCCCCCCCL )
    233           exponent_add++;
    234         /* Skip leading zeros. */
    235         else if ( nib || number )
    236         {
    237           integer_length++;
    238           number = number * 10 + nib;
    239         }
    240       }
    241     }
    242 
    243     /* Read fraction part, if any. */
    244     if ( nib == 0xA )
    245       for (;;)
    246       {
    247         /* If we entered this iteration with phase == 4, we need */
    248         /* to read a new byte.                                   */
    249         if ( phase )
    250         {
    251           p++;
    252 
    253           /* Make sure we don't read past the end. */
    254           if ( p >= limit )
    255             goto Bad;
    256         }
    257 
    258         /* Get the nibble. */
    259         nib   = ( p[0] >> phase ) & 0xF;
    260         phase = 4 - phase;
    261         if ( nib >= 10 )
    262           break;
    263 
    264         /* Skip leading zeros if possible. */
    265         if ( !nib && !number )
    266           exponent_add--;
    267         /* Only add digit if we don't overflow. */
    268         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
    269         {
    270           fraction_length++;
    271           number = number * 10 + nib;
    272         }
    273       }
    274 
    275     /* Read exponent, if any. */
    276     if ( nib == 12 )
    277     {
    278       exponent_sign = 1;
    279       nib           = 11;
    280     }
    281 
    282     if ( nib == 11 )
    283     {
    284       for (;;)
    285       {
    286         /* If we entered this iteration with phase == 4, */
    287         /* we need to read a new byte.                   */
    288         if ( phase )
    289         {
    290           p++;
    291 
    292           /* Make sure we don't read past the end. */
    293           if ( p >= limit )
    294             goto Bad;
    295         }
    296 
    297         /* Get the nibble. */
    298         nib   = ( p[0] >> phase ) & 0xF;
    299         phase = 4 - phase;
    300         if ( nib >= 10 )
    301           break;
    302 
    303         /* Arbitrarily limit exponent. */
    304         if ( exponent > 1000 )
    305           have_overflow = 1;
    306         else
    307           exponent = exponent * 10 + nib;
    308       }
    309 
    310       if ( exponent_sign )
    311         exponent = -exponent;
    312     }
    313 
    314     if ( !number )
    315       goto Exit;
    316 
    317     if ( have_overflow )
    318     {
    319       if ( exponent_sign )
    320         goto Underflow;
    321       else
    322         goto Overflow;
    323     }
    324 
    325     /* We don't check `power_ten' and `exponent_add'. */
    326     exponent += power_ten + exponent_add;
    327 
    328     if ( scaling )
    329     {
    330       /* Only use `fraction_length'. */
    331       fraction_length += integer_length;
    332       exponent        += integer_length;
    333 
    334       if ( fraction_length <= 5 )
    335       {
    336         if ( number > 0x7FFFL )
    337         {
    338           result   = FT_DivFix( number, 10 );
    339           *scaling = exponent - fraction_length + 1;
    340         }
    341         else
    342         {
    343           if ( exponent > 0 )
    344           {
    345             FT_Long  new_fraction_length, shift;
    346 
    347 
    348             /* Make `scaling' as small as possible. */
    349             new_fraction_length = FT_MIN( exponent, 5 );
    350             shift               = new_fraction_length - fraction_length;
    351 
    352             if ( shift > 0 )
    353             {
    354               exponent -= new_fraction_length;
    355               number   *= power_tens[shift];
    356               if ( number > 0x7FFFL )
    357               {
    358                 number   /= 10;
    359                 exponent += 1;
    360               }
    361             }
    362             else
    363               exponent -= fraction_length;
    364           }
    365           else
    366             exponent -= fraction_length;
    367 
    368           result   = (FT_Long)( (FT_ULong)number << 16 );
    369           *scaling = exponent;
    370         }
    371       }
    372       else
    373       {
    374         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
    375         {
    376           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
    377           *scaling = exponent - 4;
    378         }
    379         else
    380         {
    381           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
    382           *scaling = exponent - 5;
    383         }
    384       }
    385     }
    386     else
    387     {
    388       integer_length  += exponent;
    389       fraction_length -= exponent;
    390 
    391       if ( integer_length > 5 )
    392         goto Overflow;
    393       if ( integer_length < -5 )
    394         goto Underflow;
    395 
    396       /* Remove non-significant digits. */
    397       if ( integer_length < 0 )
    398       {
    399         number          /= power_tens[-integer_length];
    400         fraction_length += integer_length;
    401       }
    402 
    403       /* this can only happen if exponent was non-zero */
    404       if ( fraction_length == 10 )
    405       {
    406         number          /= 10;
    407         fraction_length -= 1;
    408       }
    409 
    410       /* Convert into 16.16 format. */
    411       if ( fraction_length > 0 )
    412       {
    413         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
    414           goto Exit;
    415 
    416         result = FT_DivFix( number, power_tens[fraction_length] );
    417       }
    418       else
    419       {
    420         number *= power_tens[-fraction_length];
    421 
    422         if ( number > 0x7FFFL )
    423           goto Overflow;
    424 
    425         result = (FT_Long)( (FT_ULong)number << 16 );
    426       }
    427     }
    428 
    429   Exit:
    430     if ( sign )
    431       result = -result;
    432 
    433     return result;
    434 
    435   Overflow:
    436     result = 0x7FFFFFFFL;
    437     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
    438     goto Exit;
    439 
    440   Underflow:
    441     result = 0;
    442     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
    443     goto Exit;
    444 
    445   Bad:
    446     result = 0;
    447     FT_TRACE4(( "!!!END OF DATA:!!!" ));
    448     goto Exit;
    449   }
    450 
    451 
    452   /* read a number, either integer or real */
    453   FT_LOCAL_DEF( FT_Long )
    454   cff_parse_num( CFF_Parser  parser,
    455                  FT_Byte**   d )
    456   {
    457     if ( **d == 30 )
    458     {
    459       /* binary-coded decimal is truncated to integer */
    460       return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
    461     }
    462 
    463     else if ( **d == 255 )
    464     {
    465       /* 16.16 fixed point is used internally for CFF2 blend results. */
    466       /* Since these are trusted values, a limit check is not needed. */
    467 
    468       /* After the 255, 4 bytes give the number.                 */
    469       /* The blend value is converted to integer, with rounding; */
    470       /* due to the right-shift we don't need the lowest byte.   */
    471 #if 0
    472       return (FT_Short)(
    473                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
    474                    ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
    475                    ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
    476                      (FT_UInt32)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
    477 #else
    478       return (FT_Short)(
    479                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
    480                    ( (FT_UInt32)*( d[0] + 2 ) <<  8 ) |
    481                      (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
    482 #endif
    483     }
    484 
    485     else
    486       return cff_parse_integer( *d, parser->limit );
    487   }
    488 
    489 
    490   /* read a floating point number, either integer or real */
    491   static FT_Fixed
    492   do_fixed( CFF_Parser  parser,
    493             FT_Byte**   d,
    494             FT_Long     scaling )
    495   {
    496     if ( **d == 30 )
    497       return cff_parse_real( *d, parser->limit, scaling, NULL );
    498     else
    499     {
    500       FT_Long  val = cff_parse_integer( *d, parser->limit );
    501 
    502 
    503       if ( scaling )
    504       {
    505         if ( FT_ABS( val ) > power_ten_limits[scaling] )
    506         {
    507           val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
    508           goto Overflow;
    509         }
    510 
    511         val *= power_tens[scaling];
    512       }
    513 
    514       if ( val > 0x7FFF )
    515       {
    516         val = 0x7FFFFFFFL;
    517         goto Overflow;
    518       }
    519       else if ( val < -0x7FFF )
    520       {
    521         val = -0x7FFFFFFFL;
    522         goto Overflow;
    523       }
    524 
    525       return (FT_Long)( (FT_ULong)val << 16 );
    526 
    527     Overflow:
    528       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
    529       return val;
    530     }
    531   }
    532 
    533 
    534   /* read a floating point number, either integer or real */
    535   static FT_Fixed
    536   cff_parse_fixed( CFF_Parser  parser,
    537                    FT_Byte**   d )
    538   {
    539     return do_fixed( parser, d, 0 );
    540   }
    541 
    542 
    543   /* read a floating point number, either integer or real, */
    544   /* but return `10^scaling' times the number read in      */
    545   static FT_Fixed
    546   cff_parse_fixed_scaled( CFF_Parser  parser,
    547                           FT_Byte**   d,
    548                           FT_Long     scaling )
    549   {
    550     return do_fixed( parser, d, scaling );
    551   }
    552 
    553 
    554   /* read a floating point number, either integer or real,     */
    555   /* and return it as precise as possible -- `scaling' returns */
    556   /* the scaling factor (as a power of 10)                     */
    557   static FT_Fixed
    558   cff_parse_fixed_dynamic( CFF_Parser  parser,
    559                            FT_Byte**   d,
    560                            FT_Long*    scaling )
    561   {
    562     FT_ASSERT( scaling );
    563 
    564     if ( **d == 30 )
    565       return cff_parse_real( *d, parser->limit, 0, scaling );
    566     else
    567     {
    568       FT_Long  number;
    569       FT_Int   integer_length;
    570 
    571 
    572       number = cff_parse_integer( d[0], d[1] );
    573 
    574       if ( number > 0x7FFFL )
    575       {
    576         for ( integer_length = 5; integer_length < 10; integer_length++ )
    577           if ( number < power_tens[integer_length] )
    578             break;
    579 
    580         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
    581         {
    582           *scaling = integer_length - 4;
    583           return FT_DivFix( number, power_tens[integer_length - 4] );
    584         }
    585         else
    586         {
    587           *scaling = integer_length - 5;
    588           return FT_DivFix( number, power_tens[integer_length - 5] );
    589         }
    590       }
    591       else
    592       {
    593         *scaling = 0;
    594         return (FT_Long)( (FT_ULong)number << 16 );
    595       }
    596     }
    597   }
    598 
    599 
    600   static FT_Error
    601   cff_parse_font_matrix( CFF_Parser  parser )
    602   {
    603     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
    604     FT_Matrix*       matrix = &dict->font_matrix;
    605     FT_Vector*       offset = &dict->font_offset;
    606     FT_ULong*        upm    = &dict->units_per_em;
    607     FT_Byte**        data   = parser->stack;
    608     FT_Error         error  = FT_ERR( Stack_Underflow );
    609 
    610 
    611     if ( parser->top >= parser->stack + 6 )
    612     {
    613       FT_Fixed  values[6];
    614       FT_Long   scalings[6];
    615 
    616       FT_Long  min_scaling, max_scaling;
    617       int      i;
    618 
    619 
    620       error = FT_Err_Ok;
    621 
    622       dict->has_font_matrix = TRUE;
    623 
    624       /* We expect a well-formed font matrix, this is, the matrix elements */
    625       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
    626       /* loss of precision, we use the magnitude of the largest matrix     */
    627       /* element to scale all other elements.  The scaling factor is then  */
    628       /* contained in the `units_per_em' value.                            */
    629 
    630       max_scaling = FT_LONG_MIN;
    631       min_scaling = FT_LONG_MAX;
    632 
    633       for ( i = 0; i < 6; i++ )
    634       {
    635         values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
    636         if ( values[i] )
    637         {
    638           if ( scalings[i] > max_scaling )
    639             max_scaling = scalings[i];
    640           if ( scalings[i] < min_scaling )
    641             min_scaling = scalings[i];
    642         }
    643       }
    644 
    645       if ( max_scaling < -9                  ||
    646            max_scaling > 0                   ||
    647            ( max_scaling - min_scaling ) < 0 ||
    648            ( max_scaling - min_scaling ) > 9 )
    649       {
    650         /* Return default matrix in case of unlikely values. */
    651 
    652         FT_TRACE1(( "cff_parse_font_matrix:"
    653                     " strange scaling values (minimum %d, maximum %d),\n"
    654                     "                      "
    655                     " using default matrix\n", min_scaling, max_scaling ));
    656 
    657         matrix->xx = 0x10000L;
    658         matrix->yx = 0;
    659         matrix->xy = 0;
    660         matrix->yy = 0x10000L;
    661         offset->x  = 0;
    662         offset->y  = 0;
    663         *upm       = 1;
    664 
    665         goto Exit;
    666       }
    667 
    668       for ( i = 0; i < 6; i++ )
    669       {
    670         FT_Fixed  value = values[i];
    671         FT_Long   divisor, half_divisor;
    672 
    673 
    674         if ( !value )
    675           continue;
    676 
    677         divisor      = power_tens[max_scaling - scalings[i]];
    678         half_divisor = divisor >> 1;
    679 
    680         if ( value < 0 )
    681         {
    682           if ( FT_LONG_MIN + half_divisor < value )
    683             values[i] = ( value - half_divisor ) / divisor;
    684           else
    685             values[i] = FT_LONG_MIN / divisor;
    686         }
    687         else
    688         {
    689           if ( FT_LONG_MAX - half_divisor > value )
    690             values[i] = ( value + half_divisor ) / divisor;
    691           else
    692             values[i] = FT_LONG_MAX / divisor;
    693         }
    694       }
    695 
    696       matrix->xx = values[0];
    697       matrix->yx = values[1];
    698       matrix->xy = values[2];
    699       matrix->yy = values[3];
    700       offset->x  = values[4];
    701       offset->y  = values[5];
    702 
    703       *upm = (FT_ULong)power_tens[-max_scaling];
    704 
    705       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
    706                   (double)matrix->xx / *upm / 65536,
    707                   (double)matrix->xy / *upm / 65536,
    708                   (double)matrix->yx / *upm / 65536,
    709                   (double)matrix->yy / *upm / 65536,
    710                   (double)offset->x  / *upm / 65536,
    711                   (double)offset->y  / *upm / 65536 ));
    712     }
    713 
    714   Exit:
    715     return error;
    716   }
    717 
    718 
    719   static FT_Error
    720   cff_parse_font_bbox( CFF_Parser  parser )
    721   {
    722     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    723     FT_BBox*         bbox = &dict->font_bbox;
    724     FT_Byte**        data = parser->stack;
    725     FT_Error         error;
    726 
    727 
    728     error = FT_ERR( Stack_Underflow );
    729 
    730     if ( parser->top >= parser->stack + 4 )
    731     {
    732       bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
    733       bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
    734       bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
    735       bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
    736       error = FT_Err_Ok;
    737 
    738       FT_TRACE4(( " [%d %d %d %d]\n",
    739                   bbox->xMin / 65536,
    740                   bbox->yMin / 65536,
    741                   bbox->xMax / 65536,
    742                   bbox->yMax / 65536 ));
    743     }
    744 
    745     return error;
    746   }
    747 
    748 
    749   static FT_Error
    750   cff_parse_private_dict( CFF_Parser  parser )
    751   {
    752     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    753     FT_Byte**        data = parser->stack;
    754     FT_Error         error;
    755 
    756 
    757     error = FT_ERR( Stack_Underflow );
    758 
    759     if ( parser->top >= parser->stack + 2 )
    760     {
    761       FT_Long  tmp;
    762 
    763 
    764       tmp = cff_parse_num( parser, data++ );
    765       if ( tmp < 0 )
    766       {
    767         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
    768         error = FT_THROW( Invalid_File_Format );
    769         goto Fail;
    770       }
    771       dict->private_size = (FT_ULong)tmp;
    772 
    773       tmp = cff_parse_num( parser, data );
    774       if ( tmp < 0 )
    775       {
    776         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
    777         error = FT_THROW( Invalid_File_Format );
    778         goto Fail;
    779       }
    780       dict->private_offset = (FT_ULong)tmp;
    781 
    782       FT_TRACE4(( " %lu %lu\n",
    783                   dict->private_size, dict->private_offset ));
    784 
    785       error = FT_Err_Ok;
    786     }
    787 
    788   Fail:
    789     return error;
    790   }
    791 
    792 
    793   /* The `MultipleMaster' operator comes before any  */
    794   /* top DICT operators that contain T2 charstrings. */
    795 
    796   static FT_Error
    797   cff_parse_multiple_master( CFF_Parser  parser )
    798   {
    799     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    800     FT_Error         error;
    801 
    802 
    803 #ifdef FT_DEBUG_LEVEL_TRACE
    804     /* beautify tracing message */
    805     if ( ft_trace_levels[FT_COMPONENT] < 4 )
    806       FT_TRACE1(( "Multiple Master CFFs not supported yet,"
    807                   " handling first master design only\n" ));
    808     else
    809       FT_TRACE1(( " (not supported yet,"
    810                   " handling first master design only)\n" ));
    811 #endif
    812 
    813     error = FT_ERR( Stack_Underflow );
    814 
    815     /* currently, we handle only the first argument */
    816     if ( parser->top >= parser->stack + 5 )
    817     {
    818       FT_Long  num_designs = cff_parse_num( parser, parser->stack );
    819 
    820 
    821       if ( num_designs > 16 || num_designs < 2 )
    822       {
    823         FT_ERROR(( "cff_parse_multiple_master:"
    824                    " Invalid number of designs\n" ));
    825         error = FT_THROW( Invalid_File_Format );
    826       }
    827       else
    828       {
    829         dict->num_designs   = (FT_UShort)num_designs;
    830         dict->num_axes      = (FT_UShort)( parser->top - parser->stack - 4 );
    831 
    832         parser->num_designs = dict->num_designs;
    833         parser->num_axes    = dict->num_axes;
    834 
    835         error = FT_Err_Ok;
    836       }
    837     }
    838 
    839     return error;
    840   }
    841 
    842 
    843   static FT_Error
    844   cff_parse_cid_ros( CFF_Parser  parser )
    845   {
    846     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    847     FT_Byte**        data = parser->stack;
    848     FT_Error         error;
    849 
    850 
    851     error = FT_ERR( Stack_Underflow );
    852 
    853     if ( parser->top >= parser->stack + 3 )
    854     {
    855       dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
    856       dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
    857       if ( **data == 30 )
    858         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
    859       dict->cid_supplement = cff_parse_num( parser, data );
    860       if ( dict->cid_supplement < 0 )
    861         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
    862                    dict->cid_supplement ));
    863       error = FT_Err_Ok;
    864 
    865       FT_TRACE4(( " %d %d %d\n",
    866                   dict->cid_registry,
    867                   dict->cid_ordering,
    868                   dict->cid_supplement ));
    869     }
    870 
    871     return error;
    872   }
    873 
    874 
    875   static FT_Error
    876   cff_parse_vsindex( CFF_Parser  parser )
    877   {
    878     /* vsindex operator can only be used in a Private DICT */
    879     CFF_Private  priv = (CFF_Private)parser->object;
    880     FT_Byte**    data = parser->stack;
    881     CFF_Blend    blend;
    882     FT_Error     error;
    883 
    884 
    885     if ( !priv || !priv->subfont )
    886     {
    887       error = FT_THROW( Invalid_File_Format );
    888       goto Exit;
    889     }
    890 
    891     blend = &priv->subfont->blend;
    892 
    893     if ( blend->usedBV )
    894     {
    895       FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
    896       error = FT_THROW( Syntax_Error );
    897       goto Exit;
    898     }
    899 
    900     priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
    901 
    902     FT_TRACE4(( " %d\n", priv->vsindex ));
    903 
    904     error = FT_Err_Ok;
    905 
    906   Exit:
    907     return error;
    908   }
    909 
    910 
    911   static FT_Error
    912   cff_parse_blend( CFF_Parser  parser )
    913   {
    914     /* blend operator can only be used in a Private DICT */
    915     CFF_Private  priv = (CFF_Private)parser->object;
    916     CFF_SubFont  subFont;
    917     CFF_Blend    blend;
    918     FT_UInt      numBlends;
    919     FT_Error     error;
    920 
    921 
    922     if ( !priv || !priv->subfont )
    923     {
    924       error = FT_THROW( Invalid_File_Format );
    925       goto Exit;
    926     }
    927 
    928     subFont = priv->subfont;
    929     blend   = &subFont->blend;
    930 
    931     if ( cff_blend_check_vector( blend,
    932                                  priv->vsindex,
    933                                  subFont->lenNDV,
    934                                  subFont->NDV ) )
    935     {
    936       error = cff_blend_build_vector( blend,
    937                                       priv->vsindex,
    938                                       subFont->lenNDV,
    939                                       subFont->NDV );
    940       if ( error )
    941         goto Exit;
    942     }
    943 
    944     numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
    945     if ( numBlends > parser->stackSize )
    946     {
    947       FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
    948       error = FT_THROW( Invalid_File_Format );
    949       goto Exit;
    950     }
    951 
    952     FT_TRACE4(( "   %d value%s blended\n",
    953                 numBlends,
    954                 numBlends == 1 ? "" : "s" ));
    955 
    956     error = cff_blend_doBlend( subFont, parser, numBlends );
    957 
    958     blend->usedBV = TRUE;
    959 
    960   Exit:
    961     return error;
    962   }
    963 
    964 
    965   /* maxstack operator increases parser and operand stacks for CFF2 */
    966   static FT_Error
    967   cff_parse_maxstack( CFF_Parser  parser )
    968   {
    969     /* maxstack operator can only be used in a Top DICT */
    970     CFF_FontRecDict  dict  = (CFF_FontRecDict)parser->object;
    971     FT_Byte**        data  = parser->stack;
    972     FT_Error         error = FT_Err_Ok;
    973 
    974 
    975     if ( !dict )
    976     {
    977       error = FT_THROW( Invalid_File_Format );
    978       goto Exit;
    979     }
    980 
    981     dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
    982     if ( dict->maxstack > CFF2_MAX_STACK )
    983       dict->maxstack = CFF2_MAX_STACK;
    984     if ( dict->maxstack < CFF2_DEFAULT_STACK )
    985       dict->maxstack = CFF2_DEFAULT_STACK;
    986 
    987     FT_TRACE4(( " %d\n", dict->maxstack ));
    988 
    989   Exit:
    990     return error;
    991   }
    992 
    993 
    994 #define CFF_FIELD_NUM( code, name, id )             \
    995           CFF_FIELD( code, name, id, cff_kind_num )
    996 #define CFF_FIELD_FIXED( code, name, id )             \
    997           CFF_FIELD( code, name, id, cff_kind_fixed )
    998 #define CFF_FIELD_FIXED_1000( code, name, id )                 \
    999           CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
   1000 #define CFF_FIELD_STRING( code, name, id )             \
   1001           CFF_FIELD( code, name, id, cff_kind_string )
   1002 #define CFF_FIELD_BOOL( code, name, id )             \
   1003           CFF_FIELD( code, name, id, cff_kind_bool )
   1004 
   1005 
   1006 #ifndef FT_CONFIG_OPTION_PIC
   1007 
   1008 
   1009 #undef  CFF_FIELD
   1010 #undef  CFF_FIELD_DELTA
   1011 
   1012 
   1013 #ifndef FT_DEBUG_LEVEL_TRACE
   1014 
   1015 
   1016 #define CFF_FIELD_CALLBACK( code, name, id ) \
   1017           {                                  \
   1018             cff_kind_callback,               \
   1019             code | CFFCODE,                  \
   1020             0, 0,                            \
   1021             cff_parse_ ## name,              \
   1022             0, 0                             \
   1023           },
   1024 
   1025 #define CFF_FIELD_BLEND( code, id ) \
   1026           {                         \
   1027             cff_kind_blend,         \
   1028             code | CFFCODE,         \
   1029             0, 0,                   \
   1030             cff_parse_blend,        \
   1031             0, 0                    \
   1032           },
   1033 
   1034 #define CFF_FIELD( code, name, id, kind ) \
   1035           {                               \
   1036             kind,                         \
   1037             code | CFFCODE,               \
   1038             FT_FIELD_OFFSET( name ),      \
   1039             FT_FIELD_SIZE( name ),        \
   1040             0, 0, 0                       \
   1041           },
   1042 
   1043 #define CFF_FIELD_DELTA( code, name, max, id ) \
   1044           {                                    \
   1045             cff_kind_delta,                    \
   1046             code | CFFCODE,                    \
   1047             FT_FIELD_OFFSET( name ),           \
   1048             FT_FIELD_SIZE_DELTA( name ),       \
   1049             0,                                 \
   1050             max,                               \
   1051             FT_FIELD_OFFSET( num_ ## name )    \
   1052           },
   1053 
   1054   static const CFF_Field_Handler  cff_field_handlers[] =
   1055   {
   1056 
   1057 #include "cfftoken.h"
   1058 
   1059     { 0, 0, 0, 0, 0, 0, 0 }
   1060   };
   1061 
   1062 
   1063 #else /* FT_DEBUG_LEVEL_TRACE */
   1064 
   1065 
   1066 
   1067 #define CFF_FIELD_CALLBACK( code, name, id ) \
   1068           {                                  \
   1069             cff_kind_callback,               \
   1070             code | CFFCODE,                  \
   1071             0, 0,                            \
   1072             cff_parse_ ## name,              \
   1073             0, 0,                            \
   1074             id                               \
   1075           },
   1076 
   1077 #define CFF_FIELD_BLEND( code, id ) \
   1078           {                         \
   1079             cff_kind_blend,         \
   1080             code | CFFCODE,         \
   1081             0, 0,                   \
   1082             cff_parse_blend,        \
   1083             0, 0,                   \
   1084             id                      \
   1085           },
   1086 
   1087 #define CFF_FIELD( code, name, id, kind ) \
   1088           {                               \
   1089             kind,                         \
   1090             code | CFFCODE,               \
   1091             FT_FIELD_OFFSET( name ),      \
   1092             FT_FIELD_SIZE( name ),        \
   1093             0, 0, 0,                      \
   1094             id                            \
   1095           },
   1096 
   1097 #define CFF_FIELD_DELTA( code, name, max, id ) \
   1098           {                                    \
   1099             cff_kind_delta,                    \
   1100             code | CFFCODE,                    \
   1101             FT_FIELD_OFFSET( name ),           \
   1102             FT_FIELD_SIZE_DELTA( name ),       \
   1103             0,                                 \
   1104             max,                               \
   1105             FT_FIELD_OFFSET( num_ ## name ),   \
   1106             id                                 \
   1107           },
   1108 
   1109   static const CFF_Field_Handler  cff_field_handlers[] =
   1110   {
   1111 
   1112 #include "cfftoken.h"
   1113 
   1114     { 0, 0, 0, 0, 0, 0, 0, 0 }
   1115   };
   1116 
   1117 
   1118 #endif /* FT_DEBUG_LEVEL_TRACE */
   1119 
   1120 
   1121 #else /* FT_CONFIG_OPTION_PIC */
   1122 
   1123 
   1124   void
   1125   FT_Destroy_Class_cff_field_handlers( FT_Library          library,
   1126                                        CFF_Field_Handler*  clazz )
   1127   {
   1128     FT_Memory  memory = library->memory;
   1129 
   1130 
   1131     if ( clazz )
   1132       FT_FREE( clazz );
   1133   }
   1134 
   1135 
   1136   FT_Error
   1137   FT_Create_Class_cff_field_handlers( FT_Library           library,
   1138                                       CFF_Field_Handler**  output_class )
   1139   {
   1140     CFF_Field_Handler*  clazz  = NULL;
   1141     FT_Error            error;
   1142     FT_Memory           memory = library->memory;
   1143 
   1144     int  i = 0;
   1145 
   1146 
   1147 #undef CFF_FIELD
   1148 #define CFF_FIELD( code, name, id, kind ) i++;
   1149 #undef CFF_FIELD_DELTA
   1150 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
   1151 #undef CFF_FIELD_CALLBACK
   1152 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
   1153 #undef CFF_FIELD_BLEND
   1154 #define CFF_FIELD_BLEND( code, id ) i++;
   1155 
   1156 #include "cfftoken.h"
   1157 
   1158     i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
   1159 
   1160     if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
   1161       return error;
   1162 
   1163     i = 0;
   1164 
   1165 
   1166 #ifndef FT_DEBUG_LEVEL_TRACE
   1167 
   1168 
   1169 #undef CFF_FIELD_CALLBACK
   1170 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
   1171           clazz[i].kind         = cff_kind_callback;   \
   1172           clazz[i].code         = code_ | CFFCODE;     \
   1173           clazz[i].offset       = 0;                   \
   1174           clazz[i].size         = 0;                   \
   1175           clazz[i].reader       = cff_parse_ ## name_; \
   1176           clazz[i].array_max    = 0;                   \
   1177           clazz[i].count_offset = 0;                   \
   1178           i++;
   1179 
   1180 #undef  CFF_FIELD
   1181 #define CFF_FIELD( code_, name_, id_, kind_ )               \
   1182           clazz[i].kind         = kind_;                    \
   1183           clazz[i].code         = code_ | CFFCODE;          \
   1184           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
   1185           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
   1186           clazz[i].reader       = 0;                        \
   1187           clazz[i].array_max    = 0;                        \
   1188           clazz[i].count_offset = 0;                        \
   1189           i++;                                              \
   1190 
   1191 #undef  CFF_FIELD_DELTA
   1192 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
   1193           clazz[i].kind         = cff_kind_delta;                   \
   1194           clazz[i].code         = code_ | CFFCODE;                  \
   1195           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
   1196           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
   1197           clazz[i].reader       = 0;                                \
   1198           clazz[i].array_max    = max_;                             \
   1199           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
   1200           i++;
   1201 
   1202 #undef  CFF_FIELD_BLEND
   1203 #define CFF_FIELD_BLEND( code_, id_ )              \
   1204           clazz[i].kind         = cff_kind_blend;  \
   1205           clazz[i].code         = code_ | CFFCODE; \
   1206           clazz[i].offset       = 0;               \
   1207           clazz[i].size         = 0;               \
   1208           clazz[i].reader       = cff_parse_blend; \
   1209           clazz[i].array_max    = 0;               \
   1210           clazz[i].count_offset = 0;               \
   1211           i++;
   1212 
   1213 #include "cfftoken.h"
   1214 
   1215     clazz[i].kind         = 0;
   1216     clazz[i].code         = 0;
   1217     clazz[i].offset       = 0;
   1218     clazz[i].size         = 0;
   1219     clazz[i].reader       = 0;
   1220     clazz[i].array_max    = 0;
   1221     clazz[i].count_offset = 0;
   1222 
   1223 
   1224 #else /* FT_DEBUG_LEVEL_TRACE */
   1225 
   1226 
   1227 #undef CFF_FIELD_CALLBACK
   1228 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
   1229           clazz[i].kind         = cff_kind_callback;   \
   1230           clazz[i].code         = code_ | CFFCODE;     \
   1231           clazz[i].offset       = 0;                   \
   1232           clazz[i].size         = 0;                   \
   1233           clazz[i].reader       = cff_parse_ ## name_; \
   1234           clazz[i].array_max    = 0;                   \
   1235           clazz[i].count_offset = 0;                   \
   1236           clazz[i].id           = id_;                 \
   1237           i++;
   1238 
   1239 #undef  CFF_FIELD
   1240 #define CFF_FIELD( code_, name_, id_, kind_ )               \
   1241           clazz[i].kind         = kind_;                    \
   1242           clazz[i].code         = code_ | CFFCODE;          \
   1243           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
   1244           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
   1245           clazz[i].reader       = 0;                        \
   1246           clazz[i].array_max    = 0;                        \
   1247           clazz[i].count_offset = 0;                        \
   1248           clazz[i].id           = id_;                      \
   1249           i++;                                              \
   1250 
   1251 #undef  CFF_FIELD_DELTA
   1252 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
   1253           clazz[i].kind         = cff_kind_delta;                   \
   1254           clazz[i].code         = code_ | CFFCODE;                  \
   1255           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
   1256           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
   1257           clazz[i].reader       = 0;                                \
   1258           clazz[i].array_max    = max_;                             \
   1259           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
   1260           clazz[i].id           = id_;                              \
   1261           i++;
   1262 
   1263 #undef  CFF_FIELD_BLEND
   1264 #define CFF_FIELD_BLEND( code_, id_ )              \
   1265           clazz[i].kind         = cff_kind_blend;  \
   1266           clazz[i].code         = code_ | CFFCODE; \
   1267           clazz[i].offset       = 0;               \
   1268           clazz[i].size         = 0;               \
   1269           clazz[i].reader       = cff_parse_blend; \
   1270           clazz[i].array_max    = 0;               \
   1271           clazz[i].count_offset = 0;               \
   1272           clazz[i].id           = id_;             \
   1273           i++;
   1274 
   1275 #include "cfftoken.h"
   1276 
   1277     clazz[i].kind         = 0;
   1278     clazz[i].code         = 0;
   1279     clazz[i].offset       = 0;
   1280     clazz[i].size         = 0;
   1281     clazz[i].reader       = 0;
   1282     clazz[i].array_max    = 0;
   1283     clazz[i].count_offset = 0;
   1284     clazz[i].id           = 0;
   1285 
   1286 
   1287 #endif /* FT_DEBUG_LEVEL_TRACE */
   1288 
   1289 
   1290     *output_class = clazz;
   1291 
   1292     return FT_Err_Ok;
   1293   }
   1294 
   1295 
   1296 #endif /* FT_CONFIG_OPTION_PIC */
   1297 
   1298 
   1299   FT_LOCAL_DEF( FT_Error )
   1300   cff_parser_run( CFF_Parser  parser,
   1301                   FT_Byte*    start,
   1302                   FT_Byte*    limit )
   1303   {
   1304 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
   1305     PSAux_Service  psaux;
   1306 #endif
   1307 
   1308     FT_Byte*    p       = start;
   1309     FT_Error    error   = FT_Err_Ok;
   1310     FT_Library  library = parser->library;
   1311 
   1312     FT_UNUSED( library );
   1313 
   1314 
   1315     parser->top    = parser->stack;
   1316     parser->start  = start;
   1317     parser->limit  = limit;
   1318     parser->cursor = start;
   1319 
   1320     while ( p < limit )
   1321     {
   1322       FT_UInt  v = *p;
   1323 
   1324       /* Opcode 31 is legacy MM T2 operator, not a number.      */
   1325       /* Opcode 255 is reserved and should not appear in fonts; */
   1326       /* it is used internally for CFF2 blends.                 */
   1327       if ( v >= 27 && v != 31 && v != 255 )
   1328       {
   1329         /* it's a number; we will push its position on the stack */
   1330         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
   1331           goto Stack_Overflow;
   1332 
   1333         *parser->top++ = p;
   1334 
   1335         /* now, skip it */
   1336         if ( v == 30 )
   1337         {
   1338           /* skip real number */
   1339           p++;
   1340           for (;;)
   1341           {
   1342             /* An unterminated floating point number at the */
   1343             /* end of a dictionary is invalid but harmless. */
   1344             if ( p >= limit )
   1345               goto Exit;
   1346             v = p[0] >> 4;
   1347             if ( v == 15 )
   1348               break;
   1349             v = p[0] & 0xF;
   1350             if ( v == 15 )
   1351               break;
   1352             p++;
   1353           }
   1354         }
   1355         else if ( v == 28 )
   1356           p += 2;
   1357         else if ( v == 29 )
   1358           p += 4;
   1359         else if ( v > 246 )
   1360           p += 1;
   1361       }
   1362 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
   1363       else if ( v == 31 )
   1364       {
   1365         /* a Type 2 charstring */
   1366 
   1367         CFF_Decoder  decoder;
   1368         CFF_FontRec  cff_rec;
   1369         FT_Byte*     charstring_base;
   1370         FT_ULong     charstring_len;
   1371 
   1372         FT_Fixed*  stack;
   1373         FT_Byte*   q;
   1374 
   1375 
   1376         charstring_base = ++p;
   1377 
   1378         /* search `endchar' operator */
   1379         for (;;)
   1380         {
   1381           if ( p >= limit )
   1382             goto Exit;
   1383           if ( *p == 14 )
   1384             break;
   1385           p++;
   1386         }
   1387 
   1388         charstring_len = (FT_ULong)( p - charstring_base ) + 1;
   1389 
   1390         /* construct CFF_Decoder object */
   1391         FT_ZERO( &decoder );
   1392         FT_ZERO( &cff_rec );
   1393 
   1394         cff_rec.top_font.font_dict.num_designs = parser->num_designs;
   1395         cff_rec.top_font.font_dict.num_axes    = parser->num_axes;
   1396         decoder.cff                            = &cff_rec;
   1397 
   1398         psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" );
   1399         if ( !psaux )
   1400         {
   1401           FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" ));
   1402           error = FT_THROW( Missing_Module );
   1403           goto Exit;
   1404         }
   1405 
   1406         error = psaux->cff_decoder_funcs->parse_charstrings_old(
   1407                   &decoder, charstring_base, charstring_len, 1 );
   1408 
   1409         /* Now copy the stack data in the temporary decoder object,    */
   1410         /* converting it back to charstring number representations     */
   1411         /* (this is ugly, I know).                                     */
   1412         /*                                                             */
   1413         /* We overwrite the original top DICT charstring under the     */
   1414         /* assumption that the charstring representation of the result */
   1415         /* of `cff_decoder_parse_charstrings' is shorter, which should */
   1416         /* be always true.                                             */
   1417 
   1418         q     = charstring_base - 1;
   1419         stack = decoder.stack;
   1420 
   1421         while ( stack < decoder.top )
   1422         {
   1423           FT_ULong  num;
   1424           FT_Bool   neg;
   1425 
   1426 
   1427           if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
   1428             goto Stack_Overflow;
   1429 
   1430           *parser->top++ = q;
   1431 
   1432           if ( *stack < 0 )
   1433           {
   1434             num = (FT_ULong)-*stack;
   1435             neg = 1;
   1436           }
   1437           else
   1438           {
   1439             num = (FT_ULong)*stack;
   1440             neg = 0;
   1441           }
   1442 
   1443           if ( num & 0xFFFFU )
   1444           {
   1445             if ( neg )
   1446               num = (FT_ULong)-num;
   1447 
   1448             *q++ = 255;
   1449             *q++ = ( num & 0xFF000000U ) >> 24;
   1450             *q++ = ( num & 0x00FF0000U ) >> 16;
   1451             *q++ = ( num & 0x0000FF00U ) >>  8;
   1452             *q++ =   num & 0x000000FFU;
   1453           }
   1454           else
   1455           {
   1456             num >>= 16;
   1457 
   1458             if ( neg )
   1459             {
   1460               if ( num <= 107 )
   1461                 *q++ = (FT_Byte)( 139 - num );
   1462               else if ( num <= 1131 )
   1463               {
   1464                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
   1465                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
   1466               }
   1467               else
   1468               {
   1469                 num = (FT_ULong)-num;
   1470 
   1471                 *q++ = 28;
   1472                 *q++ = (FT_Byte)( num >> 8 );
   1473                 *q++ = (FT_Byte)( num & 0xFF );
   1474               }
   1475             }
   1476             else
   1477             {
   1478               if ( num <= 107 )
   1479                 *q++ = (FT_Byte)( num + 139 );
   1480               else if ( num <= 1131 )
   1481               {
   1482                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
   1483                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
   1484               }
   1485               else
   1486               {
   1487                 *q++ = 28;
   1488                 *q++ = (FT_Byte)( num >> 8 );
   1489                 *q++ = (FT_Byte)( num & 0xFF );
   1490               }
   1491             }
   1492           }
   1493 
   1494           stack++;
   1495         }
   1496       }
   1497 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   1498       else
   1499       {
   1500         /* This is not a number, hence it's an operator.  Compute its code */
   1501         /* and look for it in our current list.                            */
   1502 
   1503         FT_UInt                   code;
   1504         FT_UInt                   num_args;
   1505         const CFF_Field_Handler*  field;
   1506 
   1507 
   1508         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
   1509           goto Stack_Overflow;
   1510 
   1511         num_args     = (FT_UInt)( parser->top - parser->stack );
   1512         *parser->top = p;
   1513         code         = v;
   1514 
   1515         if ( v == 12 )
   1516         {
   1517           /* two byte operator */
   1518           p++;
   1519           if ( p >= limit )
   1520             goto Syntax_Error;
   1521 
   1522           code = 0x100 | p[0];
   1523         }
   1524         code = code | parser->object_code;
   1525 
   1526         for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
   1527         {
   1528           if ( field->code == (FT_Int)code )
   1529           {
   1530             /* we found our field's handler; read it */
   1531             FT_Long   val;
   1532             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
   1533 
   1534 
   1535 #ifdef FT_DEBUG_LEVEL_TRACE
   1536             FT_TRACE4(( "  %s", field->id ));
   1537 #endif
   1538 
   1539             /* check that we have enough arguments -- except for */
   1540             /* delta encoded arrays, which can be empty          */
   1541             if ( field->kind != cff_kind_delta && num_args < 1 )
   1542               goto Stack_Underflow;
   1543 
   1544             switch ( field->kind )
   1545             {
   1546             case cff_kind_bool:
   1547             case cff_kind_string:
   1548             case cff_kind_num:
   1549               val = cff_parse_num( parser, parser->stack );
   1550               goto Store_Number;
   1551 
   1552             case cff_kind_fixed:
   1553               val = cff_parse_fixed( parser, parser->stack );
   1554               goto Store_Number;
   1555 
   1556             case cff_kind_fixed_thousand:
   1557               val = cff_parse_fixed_scaled( parser, parser->stack, 3 );
   1558 
   1559             Store_Number:
   1560               switch ( field->size )
   1561               {
   1562               case (8 / FT_CHAR_BIT):
   1563                 *(FT_Byte*)q = (FT_Byte)val;
   1564                 break;
   1565 
   1566               case (16 / FT_CHAR_BIT):
   1567                 *(FT_Short*)q = (FT_Short)val;
   1568                 break;
   1569 
   1570               case (32 / FT_CHAR_BIT):
   1571                 *(FT_Int32*)q = (FT_Int)val;
   1572                 break;
   1573 
   1574               default:  /* for 64-bit systems */
   1575                 *(FT_Long*)q = val;
   1576               }
   1577 
   1578 #ifdef FT_DEBUG_LEVEL_TRACE
   1579               switch ( field->kind )
   1580               {
   1581               case cff_kind_bool:
   1582                 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
   1583                 break;
   1584 
   1585               case cff_kind_string:
   1586                 FT_TRACE4(( " %ld (SID)\n", val ));
   1587                 break;
   1588 
   1589               case cff_kind_num:
   1590                 FT_TRACE4(( " %ld\n", val ));
   1591                 break;
   1592 
   1593               case cff_kind_fixed:
   1594                 FT_TRACE4(( " %f\n", (double)val / 65536 ));
   1595                 break;
   1596 
   1597               case cff_kind_fixed_thousand:
   1598                 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
   1599 
   1600               default:
   1601                 ; /* never reached */
   1602               }
   1603 #endif
   1604 
   1605               break;
   1606 
   1607             case cff_kind_delta:
   1608               {
   1609                 FT_Byte*   qcount = (FT_Byte*)parser->object +
   1610                                       field->count_offset;
   1611 
   1612                 FT_Byte**  data = parser->stack;
   1613 
   1614 
   1615                 if ( num_args > field->array_max )
   1616                   num_args = field->array_max;
   1617 
   1618                 FT_TRACE4(( " [" ));
   1619 
   1620                 /* store count */
   1621                 *qcount = (FT_Byte)num_args;
   1622 
   1623                 val = 0;
   1624                 while ( num_args > 0 )
   1625                 {
   1626                   val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
   1627                   switch ( field->size )
   1628                   {
   1629                   case (8 / FT_CHAR_BIT):
   1630                     *(FT_Byte*)q = (FT_Byte)val;
   1631                     break;
   1632 
   1633                   case (16 / FT_CHAR_BIT):
   1634                     *(FT_Short*)q = (FT_Short)val;
   1635                     break;
   1636 
   1637                   case (32 / FT_CHAR_BIT):
   1638                     *(FT_Int32*)q = (FT_Int)val;
   1639                     break;
   1640 
   1641                   default:  /* for 64-bit systems */
   1642                     *(FT_Long*)q = val;
   1643                   }
   1644 
   1645                   FT_TRACE4(( " %ld", val ));
   1646 
   1647                   q += field->size;
   1648                   num_args--;
   1649                 }
   1650 
   1651                 FT_TRACE4(( "]\n" ));
   1652               }
   1653               break;
   1654 
   1655             default:  /* callback or blend */
   1656               error = field->reader( parser );
   1657               if ( error )
   1658                 goto Exit;
   1659             }
   1660             goto Found;
   1661           }
   1662         }
   1663 
   1664         /* this is an unknown operator, or it is unsupported; */
   1665         /* we will ignore it for now.                         */
   1666 
   1667       Found:
   1668         /* clear stack */
   1669         /* TODO: could clear blend stack here,       */
   1670         /*       but we don't have access to subFont */
   1671         if ( field->kind != cff_kind_blend )
   1672           parser->top = parser->stack;
   1673       }
   1674       p++;
   1675     }
   1676 
   1677   Exit:
   1678     return error;
   1679 
   1680   Stack_Overflow:
   1681     error = FT_THROW( Invalid_Argument );
   1682     goto Exit;
   1683 
   1684   Stack_Underflow:
   1685     error = FT_THROW( Invalid_Argument );
   1686     goto Exit;
   1687 
   1688   Syntax_Error:
   1689     error = FT_THROW( Invalid_Argument );
   1690     goto Exit;
   1691   }
   1692 
   1693 
   1694 /* END */
   1695