/****************************************************************************
 *
 * cffparse.c
 *
 *   CFF token stream parser (body)
 *
 * Copyright (C) 1996-2021 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_QNEW_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",
                    min_scaling, max_scaling ));
        FT_TRACE1(( "                      "
                    " using default matrix\n" ));
        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 */
