tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cffparse.c (41481B)


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