/****************************************************************************
 *
 * cffparse.c
 *
 *   CFF token stream parser (body)
 *
 * Copyright (C) 1996-2023 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 ) )
      goto Exit;

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

  Exit:
    return error;
  }


  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, NULL, memory, NULL );
#endif
  }


  /* The parser limit checks in the next two functions are supposed */
  /* to detect the immediate crossing of the stream boundary.  They */
  /* shall not be triggered from the distant t2_strings buffers.    */

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


    if ( v == 28 )
    {
      if ( p + 2 > limit && limit >= p )
        goto Bad;

      val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
    }
    else if ( v == 29 )
    {
      if ( p + 4 > limit && limit >= p )
        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 ( p + 1 > limit && limit >= p )
        goto Bad;

      val = ( v - 247 ) * 256 + p[0] + 108;
    }
    else
    {
      if ( p + 1 > limit && limit >= 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( FT_Byte*  start,
                  FT_Byte*  limit,
                  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 ( p + 1 > limit && limit >= 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 ( p + 1 > limit && limit >= 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 ( p + 1 > limit && limit >= 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( *d, parser->limit, 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( *d, parser->limit );
  }


  /* 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( *d, parser->limit, scaling, NULL );
    else
    {
      FT_Long  val = cff_parse_integer( *d, parser->limit );


      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( *d, parser->limit, 0, scaling );
    else
    {
      FT_Long  number;
      FT_Int   integer_length;


      number = cff_parse_integer( *d, parser->limit );

      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, that 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 / (double)*upm / 65536,
                  (double)matrix->xy / (double)*upm / 65536,
                  (double)matrix->yx / (double)*upm / 65536,
                  (double)matrix->yy / (double)*upm / 65536,
                  (double)offset->x  / (double)*upm / 65536,
                  (double)offset->y  / (double)*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_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).                                     */
        /* The maximum required size is 5 bytes per stack element.     */
        if ( FT_QALLOC( q, 2 * sizeof ( FT_ListNode ) +
                           5 * ( decoder.top - decoder.stack ) ) )
          goto Exit;

        FT_List_Add( &parser->t2_strings, (FT_ListNode)q );

        q += 2 * sizeof ( FT_ListNode );

        for ( stack = decoder.stack; stack < decoder.top; stack++ )
        {
          FT_Long  num = *stack;


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

          *parser->top++ = q;

          if ( num & 0xFFFFU )
          {
            *q++ = 255;
            *q++ = (FT_Byte)( ( num >> 24 ) & 0xFF );
            *q++ = (FT_Byte)( ( num >> 16 ) & 0xFF );
            *q++ = (FT_Byte)( ( num >>  8 ) & 0xFF );
            *q++ = (FT_Byte)( ( num       ) & 0xFF );
          }
          else
          {
            num >>= 16;

            if ( -107 <= num && num <= 107 )
              *q++ = (FT_Byte)( num + 139 );
            else if ( 108 <= num && num <= 1131 )
            {
              *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
              *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
            }
            else if ( -1131 <= num && num <= -108 )
            {
              *q++ = (FT_Byte)( ( ( -num - 108 ) >> 8 ) + 251 );
              *q++ = (FT_Byte)( ( -num - 108) & 0xFF );
            }
            else
            {
              *q++ = 28;
              *q++ = (FT_Byte)( num >> 8 );
              *q++ = (FT_Byte)( num & 0xFF );
            }
          }
        }
      }
#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 ));
                break;

              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;

  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 */
