/****************************************************************************
 *
 * cffparse.c
 *
 *   CFF token stream parser (body)
 *
 * Copyright (C) 1996-2020 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include "cffparse.h"
#include <freetype/internal/ftstream.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/psaux.h>
#include <freetype/ftlist.h>

#include "cfferrs.h"
#include "cffload.h"


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  cffparse


  FT_LOCAL_DEF( FT_Error )
  cff_parser_init( CFF_Parser  parser,
                   FT_UInt     code,
                   void*       object,
                   FT_Library  library,
                   FT_UInt     stackSize,
                   FT_UShort   num_designs,
                   FT_UShort   num_axes )
  {
    FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
    FT_Error   error;                       /* for FT_NEW_ARRAY */


    FT_ZERO( parser );

#if 0
    parser->top         = parser->stack;
#endif
    parser->object_code = code;
    parser->object      = object;
    parser->library     = library;
    parser->num_designs = num_designs;
    parser->num_axes    = num_axes;

    /* allocate the stack buffer */
    if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
    {
      FT_FREE( parser->stack );
      goto Exit;
    }

    parser->stackSize = stackSize;
    parser->top       = parser->stack;    /* empty stack */

  Exit:
    return error;
  }


#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  static void
  finalize_t2_strings( FT_Memory  memory,
                       void*      data,
                       void*      user )
  {
    CFF_T2_String  t2 = (CFF_T2_String)data;


    FT_UNUSED( user );

    memory->free( memory, t2->start );
    memory->free( memory, data );
  }
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */


  FT_LOCAL_DEF( void )
  cff_parser_done( CFF_Parser  parser )
  {
    FT_Memory  memory = parser->library->memory;    /* for FT_FREE */


    FT_FREE( parser->stack );

#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
    FT_List_Finalize( &parser->t2_strings,
                      finalize_t2_strings,
                      memory,
                      NULL );
#endif
  }


  /* Assuming `first >= last'. */

  static FT_Error
  cff_parser_within_limits( CFF_Parser  parser,
                            FT_Byte*    first,
                            FT_Byte*    last )
  {
#ifndef CFF_CONFIG_OPTION_OLD_ENGINE

    /* Fast path for regular FreeType builds with the "new" engine; */
    /*   `first >= parser->start' can be assumed.                   */

    FT_UNUSED( first );

    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );

#else /* CFF_CONFIG_OPTION_OLD_ENGINE */

    FT_ListNode  node;


    if ( first >= parser->start &&
         last  <  parser->limit )
      return FT_Err_Ok;

    node = parser->t2_strings.head;

    while ( node )
    {
      CFF_T2_String  t2 = (CFF_T2_String)node->data;


      if ( first >= t2->start &&
           last  <  t2->limit )
        return FT_Err_Ok;

      node = node->next;
    }

    return FT_THROW( Invalid_Argument );

#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
  }


  /* read an integer */
  static FT_Long
  cff_parse_integer( CFF_Parser  parser,
                     FT_Byte*    start )
  {
    FT_Byte*  p   = start;
    FT_Int    v   = *p++;
    FT_Long   val = 0;


    if ( v == 28 )
    {
      if ( cff_parser_within_limits( parser, p, p + 1 ) )
        goto Bad;

      val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
    }
    else if ( v == 29 )
    {
      if ( cff_parser_within_limits( parser, p, p + 3 ) )
        goto Bad;

      val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
                       ( (FT_ULong)p[1] << 16 ) |
                       ( (FT_ULong)p[2] <<  8 ) |
                         (FT_ULong)p[3]         );
    }
    else if ( v < 247 )
    {
      val = v - 139;
    }
    else if ( v < 251 )
    {
      if ( cff_parser_within_limits( parser, p, p ) )
        goto Bad;

      val = ( v - 247 ) * 256 + p[0] + 108;
    }
    else
    {
      if ( cff_parser_within_limits( parser, p, p ) )
        goto Bad;

      val = -( v - 251 ) * 256 - p[0] - 108;
    }

  Exit:
    return val;

  Bad:
    val = 0;
    FT_TRACE4(( "!!!END OF DATA:!!!" ));
    goto Exit;
  }


  static const FT_Long power_tens[] =
  {
    1L,
    10L,
    100L,
    1000L,
    10000L,
    100000L,
    1000000L,
    10000000L,
    100000000L,
    1000000000L
  };

  /* maximum values allowed for multiplying      */
  /* with the corresponding `power_tens' element */
  static const FT_Long power_ten_limits[] =
  {
    FT_LONG_MAX / 1L,
    FT_LONG_MAX / 10L,
    FT_LONG_MAX / 100L,
    FT_LONG_MAX / 1000L,
    FT_LONG_MAX / 10000L,
    FT_LONG_MAX / 100000L,
    FT_LONG_MAX / 1000000L,
    FT_LONG_MAX / 10000000L,
    FT_LONG_MAX / 100000000L,
    FT_LONG_MAX / 1000000000L,
  };


  /* read a real */
  static FT_Fixed
  cff_parse_real( CFF_Parser  parser,
                  FT_Byte*    start,
                  FT_Long     power_ten,
                  FT_Long*    scaling )
  {
    FT_Byte*  p = start;
    FT_Int    nib;
    FT_UInt   phase;

    FT_Long   result, number, exponent;
    FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
    FT_Long   exponent_add, integer_length, fraction_length;


    if ( scaling )
      *scaling = 0;

    result = 0;

    number   = 0;
    exponent = 0;

    exponent_add    = 0;
    integer_length  = 0;
    fraction_length = 0;

    /* First of all, read the integer part. */
    phase = 4;

    for (;;)
    {
      /* If we entered this iteration with phase == 4, we need to */
      /* read a new byte.  This also skips past the initial 0x1E. */
      if ( phase )
      {
        p++;

        /* Make sure we don't read past the end. */
        if ( cff_parser_within_limits( parser, p, p ) )
          goto Bad;
      }

      /* Get the nibble. */
      nib   = (FT_Int)( p[0] >> phase ) & 0xF;
      phase = 4 - phase;

      if ( nib == 0xE )
        sign = 1;
      else if ( nib > 9 )
        break;
      else
      {
        /* Increase exponent if we can't add the digit. */
        if ( number >= 0xCCCCCCCL )
          exponent_add++;
        /* Skip leading zeros. */
        else if ( nib || number )
        {
          integer_length++;
          number = number * 10 + nib;
        }
      }
    }

    /* Read fraction part, if any. */
    if ( nib == 0xA )
      for (;;)
      {
        /* If we entered this iteration with phase == 4, we need */
        /* to read a new byte.                                   */
        if ( phase )
        {
          p++;

          /* Make sure we don't read past the end. */
          if ( cff_parser_within_limits( parser, p, p ) )
            goto Bad;
        }

        /* Get the nibble. */
        nib   = ( p[0] >> phase ) & 0xF;
        phase = 4 - phase;
        if ( nib >= 10 )
          break;

        /* Skip leading zeros if possible. */
        if ( !nib && !number )
          exponent_add--;
        /* Only add digit if we don't overflow. */
        else if ( number < 0xCCCCCCCL && fraction_length < 9 )
        {
          fraction_length++;
          number = number * 10 + nib;
        }
      }

    /* Read exponent, if any. */
    if ( nib == 12 )
    {
      exponent_sign = 1;
      nib           = 11;
    }

    if ( nib == 11 )
    {
      for (;;)
      {
        /* If we entered this iteration with phase == 4, */
        /* we need to read a new byte.                   */
        if ( phase )
        {
          p++;

          /* Make sure we don't read past the end. */
          if ( cff_parser_within_limits( parser, p, p ) )
            goto Bad;
        }

        /* Get the nibble. */
        nib   = ( p[0] >> phase ) & 0xF;
        phase = 4 - phase;
        if ( nib >= 10 )
          break;

        /* Arbitrarily limit exponent. */
        if ( exponent > 1000 )
          have_overflow = 1;
        else
          exponent = exponent * 10 + nib;
      }

      if ( exponent_sign )
        exponent = -exponent;
    }

    if ( !number )
      goto Exit;

    if ( have_overflow )
    {
      if ( exponent_sign )
        goto Underflow;
      else
        goto Overflow;
    }

    /* We don't check `power_ten' and `exponent_add'. */
    exponent += power_ten + exponent_add;

    if ( scaling )
    {
      /* Only use `fraction_length'. */
      fraction_length += integer_length;
      exponent        += integer_length;

      if ( fraction_length <= 5 )
      {
        if ( number > 0x7FFFL )
        {
          result   = FT_DivFix( number, 10 );
          *scaling = exponent - fraction_length + 1;
        }
        else
        {
          if ( exponent > 0 )
          {
            FT_Long  new_fraction_length, shift;


            /* Make `scaling' as small as possible. */
            new_fraction_length = FT_MIN( exponent, 5 );
            shift               = new_fraction_length - fraction_length;

            if ( shift > 0 )
            {
              exponent -= new_fraction_length;
              number   *= power_tens[shift];
              if ( number > 0x7FFFL )
              {
                number   /= 10;
                exponent += 1;
              }
            }
            else
              exponent -= fraction_length;
          }
          else
            exponent -= fraction_length;

          result   = (FT_Long)( (FT_ULong)number << 16 );
          *scaling = exponent;
        }
      }
      else
      {
        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
        {
          result   = FT_DivFix( number, power_tens[fraction_length - 4] );
          *scaling = exponent - 4;
        }
        else
        {
          result   = FT_DivFix( number, power_tens[fraction_length - 5] );
          *scaling = exponent - 5;
        }
      }
    }
    else
    {
      integer_length  += exponent;
      fraction_length -= exponent;

      if ( integer_length > 5 )
        goto Overflow;
      if ( integer_length < -5 )
        goto Underflow;

      /* Remove non-significant digits. */
      if ( integer_length < 0 )
      {
        number          /= power_tens[-integer_length];
        fraction_length += integer_length;
      }

      /* this can only happen if exponent was non-zero */
      if ( fraction_length == 10 )
      {
        number          /= 10;
        fraction_length -= 1;
      }

      /* Convert into 16.16 format. */
      if ( fraction_length > 0 )
      {
        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
          goto Exit;

        result = FT_DivFix( number, power_tens[fraction_length] );
      }
      else
      {
        number *= power_tens[-fraction_length];

        if ( number > 0x7FFFL )
          goto Overflow;

        result = (FT_Long)( (FT_ULong)number << 16 );
      }
    }

  Exit:
    if ( sign )
      result = -result;

    return result;

  Overflow:
    result = 0x7FFFFFFFL;
    FT_TRACE4(( "!!!OVERFLOW:!!!" ));
    goto Exit;

  Underflow:
    result = 0;
    FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
    goto Exit;

  Bad:
    result = 0;
    FT_TRACE4(( "!!!END OF DATA:!!!" ));
    goto Exit;
  }


  /* read a number, either integer or real */
  FT_LOCAL_DEF( FT_Long )
  cff_parse_num( CFF_Parser  parser,
                 FT_Byte**   d )
  {
    if ( **d == 30 )
    {
      /* binary-coded decimal is truncated to integer */
      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
    }

    else if ( **d == 255 )
    {
      /* 16.16 fixed point is used internally for CFF2 blend results. */
      /* Since these are trusted values, a limit check is not needed. */

      /* After the 255, 4 bytes give the number.                 */
      /* The blend value is converted to integer, with rounding; */
      /* due to the right-shift we don't need the lowest byte.   */
#if 0
      return (FT_Short)(
               ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
                   ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
                   ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
                     (FT_UInt32)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
#else
      return (FT_Short)(
               ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
                   ( (FT_UInt32)*( d[0] + 2 ) <<  8 ) |
                     (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
#endif
    }

    else
      return cff_parse_integer( parser, *d );
  }


  /* read a floating point number, either integer or real */
  static FT_Fixed
  do_fixed( CFF_Parser  parser,
            FT_Byte**   d,
            FT_Long     scaling )
  {
    if ( **d == 30 )
      return cff_parse_real( parser, *d, scaling, NULL );
    else
    {
      FT_Long  val = cff_parse_integer( parser, *d );


      if ( scaling )
      {
        if ( FT_ABS( val ) > power_ten_limits[scaling] )
        {
          val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
          goto Overflow;
        }

        val *= power_tens[scaling];
      }

      if ( val > 0x7FFF )
      {
        val = 0x7FFFFFFFL;
        goto Overflow;
      }
      else if ( val < -0x7FFF )
      {
        val = -0x7FFFFFFFL;
        goto Overflow;
      }

      return (FT_Long)( (FT_ULong)val << 16 );

    Overflow:
      FT_TRACE4(( "!!!OVERFLOW:!!!" ));
      return val;
    }
  }


  /* read a floating point number, either integer or real */
  static FT_Fixed
  cff_parse_fixed( CFF_Parser  parser,
                   FT_Byte**   d )
  {
    return do_fixed( parser, d, 0 );
  }


  /* read a floating point number, either integer or real, */
  /* but return `10^scaling' times the number read in      */
  static FT_Fixed
  cff_parse_fixed_scaled( CFF_Parser  parser,
                          FT_Byte**   d,
                          FT_Long     scaling )
  {
    return do_fixed( parser, d, scaling );
  }


  /* read a floating point number, either integer or real,     */
  /* and return it as precise as possible -- `scaling' returns */
  /* the scaling factor (as a power of 10)                     */
  static FT_Fixed
  cff_parse_fixed_dynamic( CFF_Parser  parser,
                           FT_Byte**   d,
                           FT_Long*    scaling )
  {
    FT_ASSERT( scaling );

    if ( **d == 30 )
      return cff_parse_real( parser, *d, 0, scaling );
    else
    {
      FT_Long  number;
      FT_Int   integer_length;


      number = cff_parse_integer( parser, d[0] );

      if ( number > 0x7FFFL )
      {
        for ( integer_length = 5; integer_length < 10; integer_length++ )
          if ( number < power_tens[integer_length] )
            break;

        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
        {
          *scaling = integer_length - 4;
          return FT_DivFix( number, power_tens[integer_length - 4] );
        }
        else
        {
          *scaling = integer_length - 5;
          return FT_DivFix( number, power_tens[integer_length - 5] );
        }
      }
      else
      {
        *scaling = 0;
        return (FT_Long)( (FT_ULong)number << 16 );
      }
    }
  }


  static FT_Error
  cff_parse_font_matrix( CFF_Parser  parser )
  {
    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
    FT_Matrix*       matrix = &dict->font_matrix;
    FT_Vector*       offset = &dict->font_offset;
    FT_ULong*        upm    = &dict->units_per_em;
    FT_Byte**        data   = parser->stack;


    if ( parser->top >= parser->stack + 6 )
    {
      FT_Fixed  values[6];
      FT_Long   scalings[6];

      FT_Long  min_scaling, max_scaling;
      int      i;


      dict->has_font_matrix = TRUE;

      /* We expect a well-formed font matrix, this is, the matrix elements */
      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
      /* loss of precision, we use the magnitude of the largest matrix     */
      /* element to scale all other elements.  The scaling factor is then  */
      /* contained in the `units_per_em' value.                            */

      max_scaling = FT_LONG_MIN;
      min_scaling = FT_LONG_MAX;

      for ( i = 0; i < 6; i++ )
      {
        values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
        if ( values[i] )
        {
          if ( scalings[i] > max_scaling )
            max_scaling = scalings[i];
          if ( scalings[i] < min_scaling )
            min_scaling = scalings[i];
        }
      }

      if ( max_scaling < -9                  ||
           max_scaling > 0                   ||
           ( max_scaling - min_scaling ) < 0 ||
           ( max_scaling - min_scaling ) > 9 )
      {
        FT_TRACE1(( "cff_parse_font_matrix:"
                    " strange scaling values (minimum %ld, maximum %ld),\n"
                    "                      "
                    " using default matrix\n", min_scaling, max_scaling ));
        goto Unlikely;
      }

      for ( i = 0; i < 6; i++ )
      {
        FT_Fixed  value = values[i];
        FT_Long   divisor, half_divisor;


        if ( !value )
          continue;

        divisor      = power_tens[max_scaling - scalings[i]];
        half_divisor = divisor >> 1;

        if ( value < 0 )
        {
          if ( FT_LONG_MIN + half_divisor < value )
            values[i] = ( value - half_divisor ) / divisor;
          else
            values[i] = FT_LONG_MIN / divisor;
        }
        else
        {
          if ( FT_LONG_MAX - half_divisor > value )
            values[i] = ( value + half_divisor ) / divisor;
          else
            values[i] = FT_LONG_MAX / divisor;
        }
      }

      matrix->xx = values[0];
      matrix->yx = values[1];
      matrix->xy = values[2];
      matrix->yy = values[3];
      offset->x  = values[4];
      offset->y  = values[5];

      *upm = (FT_ULong)power_tens[-max_scaling];

      FT_TRACE4(( " [%f %f %f %f %f %f]\n",
                  (double)matrix->xx / *upm / 65536,
                  (double)matrix->xy / *upm / 65536,
                  (double)matrix->yx / *upm / 65536,
                  (double)matrix->yy / *upm / 65536,
                  (double)offset->x  / *upm / 65536,
                  (double)offset->y  / *upm / 65536 ));

      if ( !FT_Matrix_Check( matrix ) )
      {
        FT_TRACE1(( "cff_parse_font_matrix:"
                    " degenerate values, using default matrix\n" ));
        goto Unlikely;
      }

      return FT_Err_Ok;
    }
    else
      return FT_THROW( Stack_Underflow );

  Unlikely:
    /* Return default matrix in case of unlikely values. */

    matrix->xx = 0x10000L;
    matrix->yx = 0;
    matrix->xy = 0;
    matrix->yy = 0x10000L;
    offset->x  = 0;
    offset->y  = 0;
    *upm       = 1;

    return FT_Err_Ok;
  }


  static FT_Error
  cff_parse_font_bbox( CFF_Parser  parser )
  {
    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    FT_BBox*         bbox = &dict->font_bbox;
    FT_Byte**        data = parser->stack;
    FT_Error         error;


    error = FT_ERR( Stack_Underflow );

    if ( parser->top >= parser->stack + 4 )
    {
      bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
      bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
      bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
      bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
      error = FT_Err_Ok;

      FT_TRACE4(( " [%ld %ld %ld %ld]\n",
                  bbox->xMin / 65536,
                  bbox->yMin / 65536,
                  bbox->xMax / 65536,
                  bbox->yMax / 65536 ));
    }

    return error;
  }


  static FT_Error
  cff_parse_private_dict( CFF_Parser  parser )
  {
    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    FT_Byte**        data = parser->stack;
    FT_Error         error;


    error = FT_ERR( Stack_Underflow );

    if ( parser->top >= parser->stack + 2 )
    {
      FT_Long  tmp;


      tmp = cff_parse_num( parser, data++ );
      if ( tmp < 0 )
      {
        FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }
      dict->private_size = (FT_ULong)tmp;

      tmp = cff_parse_num( parser, data );
      if ( tmp < 0 )
      {
        FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }
      dict->private_offset = (FT_ULong)tmp;

      FT_TRACE4(( " %lu %lu\n",
                  dict->private_size, dict->private_offset ));

      error = FT_Err_Ok;
    }

  Fail:
    return error;
  }


  /* The `MultipleMaster' operator comes before any  */
  /* top DICT operators that contain T2 charstrings. */

  static FT_Error
  cff_parse_multiple_master( CFF_Parser  parser )
  {
    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    FT_Error         error;


#ifdef FT_DEBUG_LEVEL_TRACE
    /* beautify tracing message */
    if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 )
      FT_TRACE1(( "Multiple Master CFFs not supported yet,"
                  " handling first master design only\n" ));
    else
      FT_TRACE1(( " (not supported yet,"
                  " handling first master design only)\n" ));
#endif

    error = FT_ERR( Stack_Underflow );

    /* currently, we handle only the first argument */
    if ( parser->top >= parser->stack + 5 )
    {
      FT_Long  num_designs = cff_parse_num( parser, parser->stack );


      if ( num_designs > 16 || num_designs < 2 )
      {
        FT_ERROR(( "cff_parse_multiple_master:"
                   " Invalid number of designs\n" ));
        error = FT_THROW( Invalid_File_Format );
      }
      else
      {
        dict->num_designs   = (FT_UShort)num_designs;
        dict->num_axes      = (FT_UShort)( parser->top - parser->stack - 4 );

        parser->num_designs = dict->num_designs;
        parser->num_axes    = dict->num_axes;

        error = FT_Err_Ok;
      }
    }

    return error;
  }


  static FT_Error
  cff_parse_cid_ros( CFF_Parser  parser )
  {
    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
    FT_Byte**        data = parser->stack;
    FT_Error         error;


    error = FT_ERR( Stack_Underflow );

    if ( parser->top >= parser->stack + 3 )
    {
      dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
      dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
      if ( **data == 30 )
        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
      dict->cid_supplement = cff_parse_num( parser, data );
      if ( dict->cid_supplement < 0 )
        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %ld is found\n",
                   dict->cid_supplement ));
      error = FT_Err_Ok;

      FT_TRACE4(( " %d %d %ld\n",
                  dict->cid_registry,
                  dict->cid_ordering,
                  dict->cid_supplement ));
    }

    return error;
  }


  static FT_Error
  cff_parse_vsindex( CFF_Parser  parser )
  {
    /* vsindex operator can only be used in a Private DICT */
    CFF_Private  priv = (CFF_Private)parser->object;
    FT_Byte**    data = parser->stack;
    CFF_Blend    blend;
    FT_Error     error;


    if ( !priv || !priv->subfont )
    {
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    blend = &priv->subfont->blend;

    if ( blend->usedBV )
    {
      FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
      error = FT_THROW( Syntax_Error );
      goto Exit;
    }

    priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );

    FT_TRACE4(( " %d\n", priv->vsindex ));

    error = FT_Err_Ok;

  Exit:
    return error;
  }


  static FT_Error
  cff_parse_blend( CFF_Parser  parser )
  {
    /* blend operator can only be used in a Private DICT */
    CFF_Private  priv = (CFF_Private)parser->object;
    CFF_SubFont  subFont;
    CFF_Blend    blend;
    FT_UInt      numBlends;
    FT_Error     error;


    if ( !priv || !priv->subfont )
    {
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    subFont = priv->subfont;
    blend   = &subFont->blend;

    if ( cff_blend_check_vector( blend,
                                 priv->vsindex,
                                 subFont->lenNDV,
                                 subFont->NDV ) )
    {
      error = cff_blend_build_vector( blend,
                                      priv->vsindex,
                                      subFont->lenNDV,
                                      subFont->NDV );
      if ( error )
        goto Exit;
    }

    numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
    if ( numBlends > parser->stackSize )
    {
      FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    FT_TRACE4(( "   %d value%s blended\n",
                numBlends,
                numBlends == 1 ? "" : "s" ));

    error = cff_blend_doBlend( subFont, parser, numBlends );

    blend->usedBV = TRUE;

  Exit:
    return error;
  }


  /* maxstack operator increases parser and operand stacks for CFF2 */
  static FT_Error
  cff_parse_maxstack( CFF_Parser  parser )
  {
    /* maxstack operator can only be used in a Top DICT */
    CFF_FontRecDict  dict  = (CFF_FontRecDict)parser->object;
    FT_Byte**        data  = parser->stack;
    FT_Error         error = FT_Err_Ok;


    if ( !dict )
    {
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
    if ( dict->maxstack > CFF2_MAX_STACK )
      dict->maxstack = CFF2_MAX_STACK;
    if ( dict->maxstack < CFF2_DEFAULT_STACK )
      dict->maxstack = CFF2_DEFAULT_STACK;

    FT_TRACE4(( " %d\n", dict->maxstack ));

  Exit:
    return error;
  }


#define CFF_FIELD_NUM( code, name, id )             \
          CFF_FIELD( code, name, id, cff_kind_num )
#define CFF_FIELD_FIXED( code, name, id )             \
          CFF_FIELD( code, name, id, cff_kind_fixed )
#define CFF_FIELD_FIXED_1000( code, name, id )                 \
          CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
#define CFF_FIELD_STRING( code, name, id )             \
          CFF_FIELD( code, name, id, cff_kind_string )
#define CFF_FIELD_BOOL( code, name, id )             \
          CFF_FIELD( code, name, id, cff_kind_bool )


#undef  CFF_FIELD
#undef  CFF_FIELD_DELTA


#ifndef FT_DEBUG_LEVEL_TRACE


#define CFF_FIELD_CALLBACK( code, name, id ) \
          {                                  \
            cff_kind_callback,               \
            code | CFFCODE,                  \
            0, 0,                            \
            cff_parse_ ## name,              \
            0, 0                             \
          },

#define CFF_FIELD_BLEND( code, id ) \
          {                         \
            cff_kind_blend,         \
            code | CFFCODE,         \
            0, 0,                   \
            cff_parse_blend,        \
            0, 0                    \
          },

#define CFF_FIELD( code, name, id, kind ) \
          {                               \
            kind,                         \
            code | CFFCODE,               \
            FT_FIELD_OFFSET( name ),      \
            FT_FIELD_SIZE( name ),        \
            0, 0, 0                       \
          },

#define CFF_FIELD_DELTA( code, name, max, id ) \
          {                                    \
            cff_kind_delta,                    \
            code | CFFCODE,                    \
            FT_FIELD_OFFSET( name ),           \
            FT_FIELD_SIZE_DELTA( name ),       \
            0,                                 \
            max,                               \
            FT_FIELD_OFFSET( num_ ## name )    \
          },

  static const CFF_Field_Handler  cff_field_handlers[] =
  {

#include "cfftoken.h"

    { 0, 0, 0, 0, 0, 0, 0 }
  };


#else /* FT_DEBUG_LEVEL_TRACE */



#define CFF_FIELD_CALLBACK( code, name, id ) \
          {                                  \
            cff_kind_callback,               \
            code | CFFCODE,                  \
            0, 0,                            \
            cff_parse_ ## name,              \
            0, 0,                            \
            id                               \
          },

#define CFF_FIELD_BLEND( code, id ) \
          {                         \
            cff_kind_blend,         \
            code | CFFCODE,         \
            0, 0,                   \
            cff_parse_blend,        \
            0, 0,                   \
            id                      \
          },

#define CFF_FIELD( code, name, id, kind ) \
          {                               \
            kind,                         \
            code | CFFCODE,               \
            FT_FIELD_OFFSET( name ),      \
            FT_FIELD_SIZE( name ),        \
            0, 0, 0,                      \
            id                            \
          },

#define CFF_FIELD_DELTA( code, name, max, id ) \
          {                                    \
            cff_kind_delta,                    \
            code | CFFCODE,                    \
            FT_FIELD_OFFSET( name ),           \
            FT_FIELD_SIZE_DELTA( name ),       \
            0,                                 \
            max,                               \
            FT_FIELD_OFFSET( num_ ## name ),   \
            id                                 \
          },

  static const CFF_Field_Handler  cff_field_handlers[] =
  {

#include "cfftoken.h"

    { 0, 0, 0, 0, 0, 0, 0, 0 }
  };


#endif /* FT_DEBUG_LEVEL_TRACE */


  FT_LOCAL_DEF( FT_Error )
  cff_parser_run( CFF_Parser  parser,
                  FT_Byte*    start,
                  FT_Byte*    limit )
  {
    FT_Byte*  p     = start;
    FT_Error  error = FT_Err_Ok;

#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
    PSAux_Service  psaux;

    FT_Library  library = parser->library;
    FT_Memory   memory  = library->memory;
#endif

    parser->top    = parser->stack;
    parser->start  = start;
    parser->limit  = limit;
    parser->cursor = start;

    while ( p < limit )
    {
      FT_UInt  v = *p;


      /* Opcode 31 is legacy MM T2 operator, not a number.      */
      /* Opcode 255 is reserved and should not appear in fonts; */
      /* it is used internally for CFF2 blends.                 */
      if ( v >= 27 && v != 31 && v != 255 )
      {
        /* it's a number; we will push its position on the stack */
        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
          goto Stack_Overflow;

        *parser->top++ = p;

        /* now, skip it */
        if ( v == 30 )
        {
          /* skip real number */
          p++;
          for (;;)
          {
            /* An unterminated floating point number at the */
            /* end of a dictionary is invalid but harmless. */
            if ( p >= limit )
              goto Exit;
            v = p[0] >> 4;
            if ( v == 15 )
              break;
            v = p[0] & 0xF;
            if ( v == 15 )
              break;
            p++;
          }
        }
        else if ( v == 28 )
          p += 2;
        else if ( v == 29 )
          p += 4;
        else if ( v > 246 )
          p += 1;
      }
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
      else if ( v == 31 )
      {
        /* a Type 2 charstring */

        CFF_Decoder  decoder;
        CFF_FontRec  cff_rec;
        FT_Byte*     charstring_base;
        FT_ULong     charstring_len;

        FT_Fixed*      stack;
        FT_ListNode    node;
        CFF_T2_String  t2;
        FT_Fixed       t2_size;
        FT_Byte*       q;


        charstring_base = ++p;

        /* search `endchar' operator */
        for (;;)
        {
          if ( p >= limit )
            goto Exit;
          if ( *p == 14 )
            break;
          p++;
        }

        charstring_len = (FT_ULong)( p - charstring_base ) + 1;

        /* construct CFF_Decoder object */
        FT_ZERO( &decoder );
        FT_ZERO( &cff_rec );

        cff_rec.top_font.font_dict.num_designs = parser->num_designs;
        cff_rec.top_font.font_dict.num_axes    = parser->num_axes;
        decoder.cff                            = &cff_rec;

        psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" );
        if ( !psaux )
        {
          FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" ));
          error = FT_THROW( Missing_Module );
          goto Exit;
        }

        error = psaux->cff_decoder_funcs->parse_charstrings_old(
                  &decoder, charstring_base, charstring_len, 1 );
        if ( error )
          goto Exit;

        /* Now copy the stack data in the temporary decoder object,    */
        /* converting it back to charstring number representations     */
        /* (this is ugly, I know).                                     */

        node = (FT_ListNode)memory->alloc( memory,
                                           sizeof ( FT_ListNodeRec ) );
        if ( !node )
          goto Out_Of_Memory_Error;

        FT_List_Add( &parser->t2_strings, node );

        t2 = (CFF_T2_String)memory->alloc( memory,
                                           sizeof ( CFF_T2_StringRec ) );
        if ( !t2 )
          goto Out_Of_Memory_Error;

        node->data = t2;

        /* `5' is the conservative upper bound of required bytes per stack */
        /* element.                                                        */

        t2_size = 5 * ( decoder.top - decoder.stack );

        q = (FT_Byte*)memory->alloc( memory, t2_size );
        if ( !q )
          goto Out_Of_Memory_Error;

        t2->start = q;
        t2->limit = q + t2_size;

        stack = decoder.stack;

        while ( stack < decoder.top )
        {
          FT_ULong  num;
          FT_Bool   neg;


          if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
            goto Stack_Overflow;

          *parser->top++ = q;

          if ( *stack < 0 )
          {
            num = (FT_ULong)NEG_LONG( *stack );
            neg = 1;
          }
          else
          {
            num = (FT_ULong)*stack;
            neg = 0;
          }

          if ( num & 0xFFFFU )
          {
            if ( neg )
              num = (FT_ULong)-num;

            *q++ = 255;
            *q++ = ( num & 0xFF000000U ) >> 24;
            *q++ = ( num & 0x00FF0000U ) >> 16;
            *q++ = ( num & 0x0000FF00U ) >>  8;
            *q++ =   num & 0x000000FFU;
          }
          else
          {
            num >>= 16;

            if ( neg )
            {
              if ( num <= 107 )
                *q++ = (FT_Byte)( 139 - num );
              else if ( num <= 1131 )
              {
                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
              }
              else
              {
                num = (FT_ULong)-num;

                *q++ = 28;
                *q++ = (FT_Byte)( num >> 8 );
                *q++ = (FT_Byte)( num & 0xFF );
              }
            }
            else
            {
              if ( num <= 107 )
                *q++ = (FT_Byte)( num + 139 );
              else if ( num <= 1131 )
              {
                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
              }
              else
              {
                *q++ = 28;
                *q++ = (FT_Byte)( num >> 8 );
                *q++ = (FT_Byte)( num & 0xFF );
              }
            }
          }

          stack++;
        }
      }
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
      else
      {
        /* This is not a number, hence it's an operator.  Compute its code */
        /* and look for it in our current list.                            */

        FT_UInt                   code;
        FT_UInt                   num_args;
        const CFF_Field_Handler*  field;


        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
          goto Stack_Overflow;

        num_args     = (FT_UInt)( parser->top - parser->stack );
        *parser->top = p;
        code         = v;

        if ( v == 12 )
        {
          /* two byte operator */
          p++;
          if ( p >= limit )
            goto Syntax_Error;

          code = 0x100 | p[0];
        }
        code = code | parser->object_code;

        for ( field = cff_field_handlers; field->kind; field++ )
        {
          if ( field->code == (FT_Int)code )
          {
            /* we found our field's handler; read it */
            FT_Long   val;
            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;


#ifdef FT_DEBUG_LEVEL_TRACE
            FT_TRACE4(( "  %s", field->id ));
#endif

            /* check that we have enough arguments -- except for */
            /* delta encoded arrays, which can be empty          */
            if ( field->kind != cff_kind_delta && num_args < 1 )
              goto Stack_Underflow;

            switch ( field->kind )
            {
            case cff_kind_bool:
            case cff_kind_string:
            case cff_kind_num:
              val = cff_parse_num( parser, parser->stack );
              goto Store_Number;

            case cff_kind_fixed:
              val = cff_parse_fixed( parser, parser->stack );
              goto Store_Number;

            case cff_kind_fixed_thousand:
              val = cff_parse_fixed_scaled( parser, parser->stack, 3 );

            Store_Number:
              switch ( field->size )
              {
              case (8 / FT_CHAR_BIT):
                *(FT_Byte*)q = (FT_Byte)val;
                break;

              case (16 / FT_CHAR_BIT):
                *(FT_Short*)q = (FT_Short)val;
                break;

              case (32 / FT_CHAR_BIT):
                *(FT_Int32*)q = (FT_Int)val;
                break;

              default:  /* for 64-bit systems */
                *(FT_Long*)q = val;
              }

#ifdef FT_DEBUG_LEVEL_TRACE
              switch ( field->kind )
              {
              case cff_kind_bool:
                FT_TRACE4(( " %s\n", val ? "true" : "false" ));
                break;

              case cff_kind_string:
                FT_TRACE4(( " %ld (SID)\n", val ));
                break;

              case cff_kind_num:
                FT_TRACE4(( " %ld\n", val ));
                break;

              case cff_kind_fixed:
                FT_TRACE4(( " %f\n", (double)val / 65536 ));
                break;

              case cff_kind_fixed_thousand:
                FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));

              default:
                ; /* never reached */
              }
#endif

              break;

            case cff_kind_delta:
              {
                FT_Byte*   qcount = (FT_Byte*)parser->object +
                                      field->count_offset;

                FT_Byte**  data = parser->stack;


                if ( num_args > field->array_max )
                  num_args = field->array_max;

                FT_TRACE4(( " [" ));

                /* store count */
                *qcount = (FT_Byte)num_args;

                val = 0;
                while ( num_args > 0 )
                {
                  val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
                  switch ( field->size )
                  {
                  case (8 / FT_CHAR_BIT):
                    *(FT_Byte*)q = (FT_Byte)val;
                    break;

                  case (16 / FT_CHAR_BIT):
                    *(FT_Short*)q = (FT_Short)val;
                    break;

                  case (32 / FT_CHAR_BIT):
                    *(FT_Int32*)q = (FT_Int)val;
                    break;

                  default:  /* for 64-bit systems */
                    *(FT_Long*)q = val;
                  }

                  FT_TRACE4(( " %ld", val ));

                  q += field->size;
                  num_args--;
                }

                FT_TRACE4(( "]\n" ));
              }
              break;

            default:  /* callback or blend */
              error = field->reader( parser );
              if ( error )
                goto Exit;
            }
            goto Found;
          }
        }

        /* this is an unknown operator, or it is unsupported; */
        /* we will ignore it for now.                         */

      Found:
        /* clear stack */
        /* TODO: could clear blend stack here,       */
        /*       but we don't have access to subFont */
        if ( field->kind != cff_kind_blend )
          parser->top = parser->stack;
      }
      p++;
    } /* while ( p < limit ) */

  Exit:
    return error;

#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  Out_Of_Memory_Error:
    error = FT_THROW( Out_Of_Memory );
    goto Exit;
#endif

  Stack_Overflow:
    error = FT_THROW( Invalid_Argument );
    goto Exit;

  Stack_Underflow:
    error = FT_THROW( Invalid_Argument );
    goto Exit;

  Syntax_Error:
    error = FT_THROW( Invalid_Argument );
    goto Exit;
  }


/* END */
