tor-browser

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

cffdecode.c (68442B)


      1 /****************************************************************************
      2 *
      3 * cffdecode.c
      4 *
      5 *   PostScript CFF (Type 2) decoding routines (body).
      6 *
      7 * Copyright (C) 2017-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * This file is part of the FreeType project, and may only be used,
     11 * modified, and distributed under the terms of the FreeType project
     12 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13 * this file you indicate that you have read the license and
     14 * understand and accept it fully.
     15 *
     16 */
     17 
     18 
     19 #include <freetype/freetype.h>
     20 #include <freetype/internal/ftcalc.h>
     21 #include <freetype/internal/ftdebug.h>
     22 #include <freetype/internal/ftserv.h>
     23 #include <freetype/internal/services/svcfftl.h>
     24 
     25 #include "cffdecode.h"
     26 #include "psobjs.h"
     27 
     28 #include "psauxerr.h"
     29 
     30 
     31  /**************************************************************************
     32   *
     33   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     34   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     35   * messages during execution.
     36   */
     37 #undef  FT_COMPONENT
     38 #define FT_COMPONENT  cffdecode
     39 
     40 
     41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
     42 
     43  typedef enum  CFF_Operator_
     44  {
     45    cff_op_unknown = 0,
     46 
     47    cff_op_rmoveto,
     48    cff_op_hmoveto,
     49    cff_op_vmoveto,
     50 
     51    cff_op_rlineto,
     52    cff_op_hlineto,
     53    cff_op_vlineto,
     54 
     55    cff_op_rrcurveto,
     56    cff_op_hhcurveto,
     57    cff_op_hvcurveto,
     58    cff_op_rcurveline,
     59    cff_op_rlinecurve,
     60    cff_op_vhcurveto,
     61    cff_op_vvcurveto,
     62 
     63    cff_op_flex,
     64    cff_op_hflex,
     65    cff_op_hflex1,
     66    cff_op_flex1,
     67 
     68    cff_op_endchar,
     69 
     70    cff_op_hstem,
     71    cff_op_vstem,
     72    cff_op_hstemhm,
     73    cff_op_vstemhm,
     74 
     75    cff_op_hintmask,
     76    cff_op_cntrmask,
     77    cff_op_dotsection,  /* deprecated, acts as no-op */
     78 
     79    cff_op_abs,
     80    cff_op_add,
     81    cff_op_sub,
     82    cff_op_div,
     83    cff_op_neg,
     84    cff_op_random,
     85    cff_op_mul,
     86    cff_op_sqrt,
     87 
     88    cff_op_blend,
     89 
     90    cff_op_drop,
     91    cff_op_exch,
     92    cff_op_index,
     93    cff_op_roll,
     94    cff_op_dup,
     95 
     96    cff_op_put,
     97    cff_op_get,
     98    cff_op_store,
     99    cff_op_load,
    100 
    101    cff_op_and,
    102    cff_op_or,
    103    cff_op_not,
    104    cff_op_eq,
    105    cff_op_ifelse,
    106 
    107    cff_op_callsubr,
    108    cff_op_callgsubr,
    109    cff_op_return,
    110 
    111    /* Type 1 opcodes: invalid but seen in real life */
    112    cff_op_hsbw,
    113    cff_op_closepath,
    114    cff_op_callothersubr,
    115    cff_op_pop,
    116    cff_op_seac,
    117    cff_op_sbw,
    118    cff_op_setcurrentpoint,
    119 
    120    /* do not remove */
    121    cff_op_max
    122 
    123  } CFF_Operator;
    124 
    125 
    126 #define CFF_COUNT_CHECK_WIDTH  0x80
    127 #define CFF_COUNT_EXACT        0x40
    128 #define CFF_COUNT_CLEAR_STACK  0x20
    129 
    130  /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are  */
    131  /* used for checking the width and requested numbers of arguments    */
    132  /* only; they are set to zero afterwards                             */
    133 
    134  /* the other two flags are informative only and unused currently     */
    135 
    136  static const FT_Byte  cff_argument_counts[] =
    137  {
    138    0,  /* unknown */
    139 
    140    2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
    141    1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
    142    1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
    143 
    144    0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
    145    0 | CFF_COUNT_CLEAR_STACK,
    146    0 | CFF_COUNT_CLEAR_STACK,
    147 
    148    0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
    149    0 | CFF_COUNT_CLEAR_STACK,
    150    0 | CFF_COUNT_CLEAR_STACK,
    151    0 | CFF_COUNT_CLEAR_STACK,
    152    0 | CFF_COUNT_CLEAR_STACK,
    153    0 | CFF_COUNT_CLEAR_STACK,
    154    0 | CFF_COUNT_CLEAR_STACK,
    155 
    156    13, /* flex */
    157    7,
    158    9,
    159    11,
    160 
    161    0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
    162 
    163    2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
    164    2 | CFF_COUNT_CHECK_WIDTH,
    165    2 | CFF_COUNT_CHECK_WIDTH,
    166    2 | CFF_COUNT_CHECK_WIDTH,
    167 
    168    0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
    169    0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
    170    0, /* dotsection */
    171 
    172    1, /* abs */
    173    2,
    174    2,
    175    2,
    176    1,
    177    0,
    178    2,
    179    1,
    180 
    181    1, /* blend */
    182 
    183    1, /* drop */
    184    2,
    185    1,
    186    2,
    187    1,
    188 
    189    2, /* put */
    190    1,
    191    4,
    192    3,
    193 
    194    2, /* and */
    195    2,
    196    1,
    197    2,
    198    4,
    199 
    200    1, /* callsubr */
    201    1,
    202    0,
    203 
    204    2, /* hsbw */
    205    0,
    206    0,
    207    0,
    208    5, /* seac */
    209    4, /* sbw */
    210    2  /* setcurrentpoint */
    211  };
    212 
    213 
    214  static FT_Error
    215  cff_operator_seac( CFF_Decoder*  decoder,
    216                     FT_Pos        asb,
    217                     FT_Pos        adx,
    218                     FT_Pos        ady,
    219                     FT_Int        bchar,
    220                     FT_Int        achar )
    221  {
    222    FT_Error      error;
    223    CFF_Builder*  builder = &decoder->builder;
    224    FT_Int        bchar_index, achar_index;
    225    TT_Face       face    = decoder->builder.face;
    226    FT_Vector     left_bearing, advance;
    227    FT_Byte*      charstring;
    228    FT_ULong      charstring_len;
    229    FT_Pos        glyph_width;
    230 
    231 
    232    if ( decoder->seac )
    233    {
    234      FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
    235      return FT_THROW( Syntax_Error );
    236    }
    237 
    238    adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
    239    ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
    240 
    241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    242    /* Incremental fonts don't necessarily have valid charsets.        */
    243    /* They use the character code, not the glyph index, in this case. */
    244    if ( face->root.internal->incremental_interface )
    245    {
    246      bchar_index = bchar;
    247      achar_index = achar;
    248    }
    249    else
    250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
    251    {
    252      CFF_Font cff = (CFF_Font)( face->extra.data );
    253 
    254 
    255      bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
    256      achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
    257    }
    258 
    259    if ( bchar_index < 0 || achar_index < 0 )
    260    {
    261      FT_ERROR(( "cff_operator_seac:"
    262                 " invalid seac character code arguments\n" ));
    263      return FT_THROW( Syntax_Error );
    264    }
    265 
    266    /* If we are trying to load a composite glyph, do not load the */
    267    /* accent character and return the array of subglyphs.         */
    268    if ( builder->no_recurse )
    269    {
    270      FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;
    271      FT_GlyphLoader  loader = glyph->internal->loader;
    272      FT_SubGlyph     subg;
    273 
    274 
    275      /* reallocate subglyph array if necessary */
    276      error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
    277      if ( error )
    278        goto Exit;
    279 
    280      subg = loader->current.subglyphs;
    281 
    282      /* subglyph 0 = base character */
    283      subg->index = bchar_index;
    284      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
    285                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;
    286      subg->arg1  = 0;
    287      subg->arg2  = 0;
    288      subg++;
    289 
    290      /* subglyph 1 = accent character */
    291      subg->index = achar_index;
    292      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
    293      subg->arg1  = (FT_Int)( adx >> 16 );
    294      subg->arg2  = (FT_Int)( ady >> 16 );
    295 
    296      /* set up remaining glyph fields */
    297      glyph->num_subglyphs = 2;
    298      glyph->subglyphs     = loader->base.subglyphs;
    299      glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
    300 
    301      loader->current.num_subglyphs = 2;
    302    }
    303 
    304    FT_GlyphLoader_Prepare( builder->loader );
    305 
    306    /* First load `bchar' in builder */
    307    error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
    308                                         &charstring, &charstring_len );
    309    if ( !error )
    310    {
    311      /* the seac operator must not be nested */
    312      decoder->seac = TRUE;
    313      error = cff_decoder_parse_charstrings( decoder, charstring,
    314                                             charstring_len, 0 );
    315      decoder->seac = FALSE;
    316 
    317      decoder->free_glyph_callback( face, &charstring, charstring_len );
    318 
    319      if ( error )
    320        goto Exit;
    321    }
    322 
    323    /* Save the left bearing, advance and glyph width of the base */
    324    /* character as they will be erased by the next load.         */
    325 
    326    left_bearing = builder->left_bearing;
    327    advance      = builder->advance;
    328    glyph_width  = decoder->glyph_width;
    329 
    330    builder->left_bearing.x = 0;
    331    builder->left_bearing.y = 0;
    332 
    333    builder->pos_x = SUB_LONG( adx, asb );
    334    builder->pos_y = ady;
    335 
    336    /* Now load `achar' on top of the base outline. */
    337    error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
    338                                         &charstring, &charstring_len );
    339    if ( !error )
    340    {
    341      /* the seac operator must not be nested */
    342      decoder->seac = TRUE;
    343      error = cff_decoder_parse_charstrings( decoder, charstring,
    344                                             charstring_len, 0 );
    345      decoder->seac = FALSE;
    346 
    347      decoder->free_glyph_callback( face, &charstring, charstring_len );
    348 
    349      if ( error )
    350        goto Exit;
    351    }
    352 
    353    /* Restore the left side bearing, advance and glyph width */
    354    /* of the base character.                                 */
    355    builder->left_bearing = left_bearing;
    356    builder->advance      = advance;
    357    decoder->glyph_width  = glyph_width;
    358 
    359    builder->pos_x = 0;
    360    builder->pos_y = 0;
    361 
    362  Exit:
    363    return error;
    364  }
    365 
    366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
    367 
    368 
    369  /*************************************************************************/
    370  /*************************************************************************/
    371  /*************************************************************************/
    372  /**********                                                      *********/
    373  /**********                                                      *********/
    374  /**********             GENERIC CHARSTRING PARSING               *********/
    375  /**********                                                      *********/
    376  /**********                                                      *********/
    377  /*************************************************************************/
    378  /*************************************************************************/
    379  /*************************************************************************/
    380 
    381  /**************************************************************************
    382   *
    383   * @Function:
    384   *   cff_compute_bias
    385   *
    386   * @Description:
    387   *   Computes the bias value in dependence of the number of glyph
    388   *   subroutines.
    389   *
    390   * @Input:
    391   *   in_charstring_type ::
    392   *     The `CharstringType' value of the top DICT
    393   *     dictionary.
    394   *
    395   *   num_subrs ::
    396   *     The number of glyph subroutines.
    397   *
    398   * @Return:
    399   *   The bias value.
    400   */
    401  static FT_Int
    402  cff_compute_bias( FT_Int   in_charstring_type,
    403                    FT_UInt  num_subrs )
    404  {
    405    FT_Int  result;
    406 
    407 
    408    if ( in_charstring_type == 1 )
    409      result = 0;
    410    else if ( num_subrs < 1240 )
    411      result = 107;
    412    else if ( num_subrs < 33900U )
    413      result = 1131;
    414    else
    415      result = 32768U;
    416 
    417    return result;
    418  }
    419 
    420 
    421  FT_LOCAL_DEF( FT_Int )
    422  cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,
    423                                   FT_Int    charcode )
    424  {
    425    FT_UInt    n;
    426    FT_UShort  glyph_sid;
    427 
    428    FT_Service_CFFLoad  cffload;
    429 
    430 
    431    /* CID-keyed fonts don't have glyph names */
    432    if ( !cff->charset.sids )
    433      return -1;
    434 
    435    /* check range of standard char code */
    436    if ( charcode < 0 || charcode > 255 )
    437      return -1;
    438 
    439 #if 0
    440    /* retrieve cffload from list of current modules */
    441    FT_Service_CFFLoad  cffload;
    442 
    443 
    444    FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
    445    if ( !cffload )
    446    {
    447      FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
    448                 " the `cffload' module is not available\n" ));
    449      return FT_THROW( Unimplemented_Feature );
    450    }
    451 #endif
    452 
    453    cffload = (FT_Service_CFFLoad)cff->cffload;
    454 
    455    /* Get code to SID mapping from `cff_standard_encoding'. */
    456    glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
    457 
    458    for ( n = 0; n < cff->num_glyphs; n++ )
    459    {
    460      if ( cff->charset.sids[n] == glyph_sid )
    461        return (FT_Int)n;
    462    }
    463 
    464    return -1;
    465  }
    466 
    467 
    468 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
    469 
    470  /**************************************************************************
    471   *
    472   * @Function:
    473   *   cff_decoder_parse_charstrings
    474   *
    475   * @Description:
    476   *   Parses a given Type 2 charstrings program.
    477   *
    478   * @InOut:
    479   *   decoder ::
    480   *     The current Type 1 decoder.
    481   *
    482   * @Input:
    483   *   charstring_base ::
    484   *     The base of the charstring stream.
    485   *
    486   *   charstring_len ::
    487   *     The length in bytes of the charstring stream.
    488   *
    489   *   in_dict ::
    490   *     Set to 1 if function is called from top or
    491   *     private DICT (needed for Multiple Master CFFs).
    492   *
    493   * @Return:
    494   *   FreeType error code.  0 means success.
    495   */
    496  FT_LOCAL_DEF( FT_Error )
    497  cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
    498                                 FT_Byte*      charstring_base,
    499                                 FT_ULong      charstring_len,
    500                                 FT_Bool       in_dict )
    501  {
    502    FT_Error           error;
    503    CFF_Decoder_Zone*  zone;
    504    FT_Byte*           ip;
    505    FT_Byte*           limit;
    506    CFF_Builder*       builder = &decoder->builder;
    507    FT_Pos             x, y;
    508    FT_Fixed*          stack;
    509    FT_Int             charstring_type =
    510                         decoder->cff->top_font.font_dict.charstring_type;
    511    FT_UShort          num_designs =
    512                         decoder->cff->top_font.font_dict.num_designs;
    513    FT_UShort          num_axes =
    514                         decoder->cff->top_font.font_dict.num_axes;
    515 
    516    T2_Hints_Funcs  hinter;
    517 
    518 
    519    /* set default width */
    520    decoder->num_hints  = 0;
    521    decoder->read_width = 1;
    522 
    523    /* initialize the decoder */
    524    decoder->top  = decoder->stack;
    525    decoder->zone = decoder->zones;
    526    zone          = decoder->zones;
    527    stack         = decoder->top;
    528 
    529    hinter = (T2_Hints_Funcs)builder->hints_funcs;
    530 
    531    builder->path_begun = 0;
    532 
    533    if ( !charstring_base )
    534      return FT_Err_Ok;
    535 
    536    zone->base           = charstring_base;
    537    limit = zone->limit  = charstring_base + charstring_len;
    538    ip    = zone->cursor = zone->base;
    539 
    540    error = FT_Err_Ok;
    541 
    542    x = builder->pos_x;
    543    y = builder->pos_y;
    544 
    545    /* begin hints recording session, if any */
    546    if ( hinter )
    547      hinter->open( hinter->hints );
    548 
    549    /* now execute loop */
    550    while ( ip < limit )
    551    {
    552      CFF_Operator  op;
    553      FT_Byte       v;
    554 
    555 
    556      /*********************************************************************
    557       *
    558       * Decode operator or operand
    559       */
    560      v = *ip++;
    561      if ( v >= 32 || v == 28 )
    562      {
    563        FT_Int    shift = 16;
    564        FT_Int32  val;
    565 
    566 
    567        /* this is an operand, push it on the stack */
    568 
    569        /* if we use shifts, all computations are done with unsigned */
    570        /* values; the conversion to a signed value is the last step */
    571        if ( v == 28 )
    572        {
    573          if ( ip + 1 >= limit )
    574            goto Syntax_Error;
    575          val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
    576          ip += 2;
    577        }
    578        else if ( v < 247 )
    579          val = (FT_Int32)v - 139;
    580        else if ( v < 251 )
    581        {
    582          if ( ip >= limit )
    583            goto Syntax_Error;
    584          val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
    585        }
    586        else if ( v < 255 )
    587        {
    588          if ( ip >= limit )
    589            goto Syntax_Error;
    590          val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
    591        }
    592        else
    593        {
    594          if ( ip + 3 >= limit )
    595            goto Syntax_Error;
    596          val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
    597                            ( (FT_UInt32)ip[1] << 16 ) |
    598                            ( (FT_UInt32)ip[2] <<  8 ) |
    599                              (FT_UInt32)ip[3]         );
    600          ip += 4;
    601          if ( charstring_type == 2 )
    602            shift = 0;
    603        }
    604        if ( decoder->top - stack >= CFF_MAX_OPERANDS )
    605          goto Stack_Overflow;
    606 
    607        val             = (FT_Int32)( (FT_UInt32)val << shift );
    608        *decoder->top++ = val;
    609 
    610 #ifdef FT_DEBUG_LEVEL_TRACE
    611        if ( !( val & 0xFFFFL ) )
    612          FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
    613        else
    614          FT_TRACE4(( " %.5f", val / 65536.0 ));
    615 #endif
    616 
    617      }
    618      else
    619      {
    620        /* The specification says that normally arguments are to be taken */
    621        /* from the bottom of the stack.  However, this seems not to be   */
    622        /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
    623        /* arguments similar to a PS interpreter.                         */
    624 
    625        FT_Fixed*  args     = decoder->top;
    626        FT_Int     num_args = (FT_Int)( args - decoder->stack );
    627        FT_Int     req_args;
    628 
    629 
    630        /* find operator */
    631        op = cff_op_unknown;
    632 
    633        switch ( v )
    634        {
    635        case 1:
    636          op = cff_op_hstem;
    637          break;
    638        case 3:
    639          op = cff_op_vstem;
    640          break;
    641        case 4:
    642          op = cff_op_vmoveto;
    643          break;
    644        case 5:
    645          op = cff_op_rlineto;
    646          break;
    647        case 6:
    648          op = cff_op_hlineto;
    649          break;
    650        case 7:
    651          op = cff_op_vlineto;
    652          break;
    653        case 8:
    654          op = cff_op_rrcurveto;
    655          break;
    656        case 9:
    657          op = cff_op_closepath;
    658          break;
    659        case 10:
    660          op = cff_op_callsubr;
    661          break;
    662        case 11:
    663          op = cff_op_return;
    664          break;
    665        case 12:
    666          if ( ip >= limit )
    667            goto Syntax_Error;
    668          v = *ip++;
    669 
    670          switch ( v )
    671          {
    672          case 0:
    673            op = cff_op_dotsection;
    674            break;
    675          case 1: /* this is actually the Type1 vstem3 operator */
    676            op = cff_op_vstem;
    677            break;
    678          case 2: /* this is actually the Type1 hstem3 operator */
    679            op = cff_op_hstem;
    680            break;
    681          case 3:
    682            op = cff_op_and;
    683            break;
    684          case 4:
    685            op = cff_op_or;
    686            break;
    687          case 5:
    688            op = cff_op_not;
    689            break;
    690          case 6:
    691            op = cff_op_seac;
    692            break;
    693          case 7:
    694            op = cff_op_sbw;
    695            break;
    696          case 8:
    697            op = cff_op_store;
    698            break;
    699          case 9:
    700            op = cff_op_abs;
    701            break;
    702          case 10:
    703            op = cff_op_add;
    704            break;
    705          case 11:
    706            op = cff_op_sub;
    707            break;
    708          case 12:
    709            op = cff_op_div;
    710            break;
    711          case 13:
    712            op = cff_op_load;
    713            break;
    714          case 14:
    715            op = cff_op_neg;
    716            break;
    717          case 15:
    718            op = cff_op_eq;
    719            break;
    720          case 16:
    721            op = cff_op_callothersubr;
    722            break;
    723          case 17:
    724            op = cff_op_pop;
    725            break;
    726          case 18:
    727            op = cff_op_drop;
    728            break;
    729          case 20:
    730            op = cff_op_put;
    731            break;
    732          case 21:
    733            op = cff_op_get;
    734            break;
    735          case 22:
    736            op = cff_op_ifelse;
    737            break;
    738          case 23:
    739            op = cff_op_random;
    740            break;
    741          case 24:
    742            op = cff_op_mul;
    743            break;
    744          case 26:
    745            op = cff_op_sqrt;
    746            break;
    747          case 27:
    748            op = cff_op_dup;
    749            break;
    750          case 28:
    751            op = cff_op_exch;
    752            break;
    753          case 29:
    754            op = cff_op_index;
    755            break;
    756          case 30:
    757            op = cff_op_roll;
    758            break;
    759          case 33:
    760            op = cff_op_setcurrentpoint;
    761            break;
    762          case 34:
    763            op = cff_op_hflex;
    764            break;
    765          case 35:
    766            op = cff_op_flex;
    767            break;
    768          case 36:
    769            op = cff_op_hflex1;
    770            break;
    771          case 37:
    772            op = cff_op_flex1;
    773            break;
    774          default:
    775            FT_TRACE4(( " unknown op (12, %d)\n", v ));
    776            break;
    777          }
    778          break;
    779        case 13:
    780          op = cff_op_hsbw;
    781          break;
    782        case 14:
    783          op = cff_op_endchar;
    784          break;
    785        case 16:
    786          op = cff_op_blend;
    787          break;
    788        case 18:
    789          op = cff_op_hstemhm;
    790          break;
    791        case 19:
    792          op = cff_op_hintmask;
    793          break;
    794        case 20:
    795          op = cff_op_cntrmask;
    796          break;
    797        case 21:
    798          op = cff_op_rmoveto;
    799          break;
    800        case 22:
    801          op = cff_op_hmoveto;
    802          break;
    803        case 23:
    804          op = cff_op_vstemhm;
    805          break;
    806        case 24:
    807          op = cff_op_rcurveline;
    808          break;
    809        case 25:
    810          op = cff_op_rlinecurve;
    811          break;
    812        case 26:
    813          op = cff_op_vvcurveto;
    814          break;
    815        case 27:
    816          op = cff_op_hhcurveto;
    817          break;
    818        case 29:
    819          op = cff_op_callgsubr;
    820          break;
    821        case 30:
    822          op = cff_op_vhcurveto;
    823          break;
    824        case 31:
    825          op = cff_op_hvcurveto;
    826          break;
    827        default:
    828          FT_TRACE4(( " unknown op (%d)\n", v ));
    829          break;
    830        }
    831 
    832        if ( op == cff_op_unknown )
    833          continue;
    834 
    835        /* in Multiple Master CFFs, T2 charstrings can appear in */
    836        /* dictionaries, but some operators are prohibited       */
    837        if ( in_dict )
    838        {
    839          switch ( op )
    840          {
    841          case cff_op_hstem:
    842          case cff_op_vstem:
    843          case cff_op_vmoveto:
    844          case cff_op_rlineto:
    845          case cff_op_hlineto:
    846          case cff_op_vlineto:
    847          case cff_op_rrcurveto:
    848          case cff_op_hstemhm:
    849          case cff_op_hintmask:
    850          case cff_op_cntrmask:
    851          case cff_op_rmoveto:
    852          case cff_op_hmoveto:
    853          case cff_op_vstemhm:
    854          case cff_op_rcurveline:
    855          case cff_op_rlinecurve:
    856          case cff_op_vvcurveto:
    857          case cff_op_hhcurveto:
    858          case cff_op_vhcurveto:
    859          case cff_op_hvcurveto:
    860          case cff_op_hflex:
    861          case cff_op_flex:
    862          case cff_op_hflex1:
    863          case cff_op_flex1:
    864          case cff_op_callsubr:
    865          case cff_op_callgsubr:
    866            /* deprecated opcodes */
    867          case cff_op_dotsection:
    868            /* invalid Type 1 opcodes */
    869          case cff_op_hsbw:
    870          case cff_op_closepath:
    871          case cff_op_callothersubr:
    872          case cff_op_seac:
    873          case cff_op_sbw:
    874          case cff_op_setcurrentpoint:
    875            goto MM_Error;
    876 
    877          default:
    878            break;
    879          }
    880        }
    881 
    882        /* check arguments */
    883        req_args = cff_argument_counts[op];
    884        if ( req_args & CFF_COUNT_CHECK_WIDTH )
    885        {
    886          if ( num_args > 0 && decoder->read_width )
    887          {
    888            /* If `nominal_width' is non-zero, the number is really a      */
    889            /* difference against `nominal_width'.  Else, the number here  */
    890            /* is truly a width, not a difference against `nominal_width'. */
    891            /* If the font does not set `nominal_width', then              */
    892            /* `nominal_width' defaults to zero, and so we can set         */
    893            /* `glyph_width' to `nominal_width' plus number on the stack   */
    894            /* -- for either case.                                         */
    895 
    896            FT_Int  set_width_ok;
    897 
    898 
    899            switch ( op )
    900            {
    901            case cff_op_hmoveto:
    902            case cff_op_vmoveto:
    903              set_width_ok = num_args & 2;
    904              break;
    905 
    906            case cff_op_hstem:
    907            case cff_op_vstem:
    908            case cff_op_hstemhm:
    909            case cff_op_vstemhm:
    910            case cff_op_rmoveto:
    911            case cff_op_hintmask:
    912            case cff_op_cntrmask:
    913              set_width_ok = num_args & 1;
    914              break;
    915 
    916            case cff_op_endchar:
    917              /* If there is a width specified for endchar, we either have */
    918              /* 1 argument or 5 arguments.  We like to argue.             */
    919              set_width_ok = in_dict
    920                               ? 0
    921                               : ( ( num_args == 5 ) || ( num_args == 1 ) );
    922              break;
    923 
    924            default:
    925              set_width_ok = 0;
    926              break;
    927            }
    928 
    929            if ( set_width_ok )
    930            {
    931              decoder->glyph_width = decoder->nominal_width +
    932                                       ( stack[0] >> 16 );
    933 
    934              if ( decoder->width_only )
    935              {
    936                /* we only want the advance width; stop here */
    937                break;
    938              }
    939 
    940              /* Consumed an argument. */
    941              num_args--;
    942            }
    943          }
    944 
    945          decoder->read_width = 0;
    946          req_args            = 0;
    947        }
    948 
    949        req_args &= 0x000F;
    950        if ( num_args < req_args )
    951          goto Stack_Underflow;
    952        args     -= req_args;
    953        num_args -= req_args;
    954 
    955        /* At this point, `args' points to the first argument of the  */
    956        /* operand in case `req_args' isn't zero.  Otherwise, we have */
    957        /* to adjust `args' manually.                                 */
    958 
    959        /* Note that we only pop arguments from the stack which we    */
    960        /* really need and can digest so that we can continue in case */
    961        /* of superfluous stack elements.                             */
    962 
    963        switch ( op )
    964        {
    965        case cff_op_hstem:
    966        case cff_op_vstem:
    967        case cff_op_hstemhm:
    968        case cff_op_vstemhm:
    969          /* the number of arguments is always even here */
    970          FT_TRACE4(( "%s\n",
    971              op == cff_op_hstem   ? " hstem"   :
    972            ( op == cff_op_vstem   ? " vstem"   :
    973            ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
    974 
    975          if ( hinter )
    976            hinter->stems( hinter->hints,
    977                           ( op == cff_op_hstem || op == cff_op_hstemhm ),
    978                           num_args / 2,
    979                           args - ( num_args & ~1 ) );
    980 
    981          decoder->num_hints += num_args / 2;
    982          args = stack;
    983          break;
    984 
    985        case cff_op_hintmask:
    986        case cff_op_cntrmask:
    987          FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
    988                                                  : " cntrmask" ));
    989 
    990          /* implement vstem when needed --                        */
    991          /* the specification doesn't say it, but this also works */
    992          /* with the 'cntrmask' operator                          */
    993          /*                                                       */
    994          if ( num_args > 0 )
    995          {
    996            if ( hinter )
    997              hinter->stems( hinter->hints,
    998                             0,
    999                             num_args / 2,
   1000                             args - ( num_args & ~1 ) );
   1001 
   1002            decoder->num_hints += num_args / 2;
   1003          }
   1004 
   1005          /* In a valid charstring there must be at least one byte */
   1006          /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
   1007          /* instruction).  Additionally, there must be space for  */
   1008          /* `num_hints' bits.                                     */
   1009 
   1010          if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
   1011            goto Syntax_Error;
   1012 
   1013          if ( hinter )
   1014          {
   1015            if ( op == cff_op_hintmask )
   1016              hinter->hintmask( hinter->hints,
   1017                                (FT_UInt)builder->current->n_points,
   1018                                (FT_UInt)decoder->num_hints,
   1019                                ip );
   1020            else
   1021              hinter->counter( hinter->hints,
   1022                               (FT_UInt)decoder->num_hints,
   1023                               ip );
   1024          }
   1025 
   1026 #ifdef FT_DEBUG_LEVEL_TRACE
   1027          {
   1028            FT_UInt  maskbyte;
   1029 
   1030 
   1031            FT_TRACE4(( " (maskbytes:" ));
   1032 
   1033            for ( maskbyte = 0;
   1034                  maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
   1035                  maskbyte++, ip++ )
   1036              FT_TRACE4(( " 0x%02X", *ip ));
   1037 
   1038            FT_TRACE4(( ")\n" ));
   1039          }
   1040 #else
   1041          ip += ( decoder->num_hints + 7 ) >> 3;
   1042 #endif
   1043          args = stack;
   1044          break;
   1045 
   1046        case cff_op_rmoveto:
   1047          FT_TRACE4(( " rmoveto\n" ));
   1048 
   1049          cff_builder_close_contour( builder );
   1050          builder->path_begun = 0;
   1051          x    = ADD_LONG( x, args[-2] );
   1052          y    = ADD_LONG( y, args[-1] );
   1053          args = stack;
   1054          break;
   1055 
   1056        case cff_op_vmoveto:
   1057          FT_TRACE4(( " vmoveto\n" ));
   1058 
   1059          cff_builder_close_contour( builder );
   1060          builder->path_begun = 0;
   1061          y    = ADD_LONG( y, args[-1] );
   1062          args = stack;
   1063          break;
   1064 
   1065        case cff_op_hmoveto:
   1066          FT_TRACE4(( " hmoveto\n" ));
   1067 
   1068          cff_builder_close_contour( builder );
   1069          builder->path_begun = 0;
   1070          x    = ADD_LONG( x, args[-1] );
   1071          args = stack;
   1072          break;
   1073 
   1074        case cff_op_rlineto:
   1075          FT_TRACE4(( " rlineto\n" ));
   1076 
   1077          if ( cff_builder_start_point( builder, x, y )  ||
   1078               cff_check_points( builder, num_args / 2 ) )
   1079            goto Fail;
   1080 
   1081          if ( num_args < 2 )
   1082            goto Stack_Underflow;
   1083 
   1084          args -= num_args & ~1;
   1085          while ( args < decoder->top )
   1086          {
   1087            x = ADD_LONG( x, args[0] );
   1088            y = ADD_LONG( y, args[1] );
   1089            cff_builder_add_point( builder, x, y, 1 );
   1090            args += 2;
   1091          }
   1092          args = stack;
   1093          break;
   1094 
   1095        case cff_op_hlineto:
   1096        case cff_op_vlineto:
   1097          {
   1098            FT_Int  phase = ( op == cff_op_hlineto );
   1099 
   1100 
   1101            FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
   1102                                                     : " vlineto" ));
   1103 
   1104            if ( num_args < 0 )
   1105              goto Stack_Underflow;
   1106 
   1107            /* there exist subsetted fonts (found in PDFs) */
   1108            /* which call `hlineto' without arguments      */
   1109            if ( num_args == 0 )
   1110              break;
   1111 
   1112            if ( cff_builder_start_point( builder, x, y ) ||
   1113                 cff_check_points( builder, num_args )    )
   1114              goto Fail;
   1115 
   1116            args = stack;
   1117            while ( args < decoder->top )
   1118            {
   1119              if ( phase )
   1120                x = ADD_LONG( x, args[0] );
   1121              else
   1122                y = ADD_LONG( y, args[0] );
   1123 
   1124              if ( cff_builder_add_point1( builder, x, y ) )
   1125                goto Fail;
   1126 
   1127              args++;
   1128              phase ^= 1;
   1129            }
   1130            args = stack;
   1131          }
   1132          break;
   1133 
   1134        case cff_op_rrcurveto:
   1135          {
   1136            FT_Int  nargs;
   1137 
   1138 
   1139            FT_TRACE4(( " rrcurveto\n" ));
   1140 
   1141            if ( num_args < 6 )
   1142              goto Stack_Underflow;
   1143 
   1144            nargs = num_args - num_args % 6;
   1145 
   1146            if ( cff_builder_start_point( builder, x, y ) ||
   1147                 cff_check_points( builder, nargs / 2 )   )
   1148              goto Fail;
   1149 
   1150            args -= nargs;
   1151            while ( args < decoder->top )
   1152            {
   1153              x = ADD_LONG( x, args[0] );
   1154              y = ADD_LONG( y, args[1] );
   1155              cff_builder_add_point( builder, x, y, 0 );
   1156 
   1157              x = ADD_LONG( x, args[2] );
   1158              y = ADD_LONG( y, args[3] );
   1159              cff_builder_add_point( builder, x, y, 0 );
   1160 
   1161              x = ADD_LONG( x, args[4] );
   1162              y = ADD_LONG( y, args[5] );
   1163              cff_builder_add_point( builder, x, y, 1 );
   1164 
   1165              args += 6;
   1166            }
   1167            args = stack;
   1168          }
   1169          break;
   1170 
   1171        case cff_op_vvcurveto:
   1172          {
   1173            FT_Int  nargs;
   1174 
   1175 
   1176            FT_TRACE4(( " vvcurveto\n" ));
   1177 
   1178            if ( num_args < 4 )
   1179              goto Stack_Underflow;
   1180 
   1181            /* if num_args isn't of the form 4n or 4n+1, */
   1182            /* we enforce it by clearing the second bit  */
   1183 
   1184            nargs = num_args & ~2;
   1185 
   1186            if ( cff_builder_start_point( builder, x, y ) )
   1187              goto Fail;
   1188 
   1189            args -= nargs;
   1190 
   1191            if ( nargs & 1 )
   1192            {
   1193              x = ADD_LONG( x, args[0] );
   1194              args++;
   1195              nargs--;
   1196            }
   1197 
   1198            if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
   1199              goto Fail;
   1200 
   1201            while ( args < decoder->top )
   1202            {
   1203              y = ADD_LONG( y, args[0] );
   1204              cff_builder_add_point( builder, x, y, 0 );
   1205 
   1206              x = ADD_LONG( x, args[1] );
   1207              y = ADD_LONG( y, args[2] );
   1208              cff_builder_add_point( builder, x, y, 0 );
   1209 
   1210              y = ADD_LONG( y, args[3] );
   1211              cff_builder_add_point( builder, x, y, 1 );
   1212 
   1213              args += 4;
   1214            }
   1215            args = stack;
   1216          }
   1217          break;
   1218 
   1219        case cff_op_hhcurveto:
   1220          {
   1221            FT_Int  nargs;
   1222 
   1223 
   1224            FT_TRACE4(( " hhcurveto\n" ));
   1225 
   1226            if ( num_args < 4 )
   1227              goto Stack_Underflow;
   1228 
   1229            /* if num_args isn't of the form 4n or 4n+1, */
   1230            /* we enforce it by clearing the second bit  */
   1231 
   1232            nargs = num_args & ~2;
   1233 
   1234            if ( cff_builder_start_point( builder, x, y ) )
   1235              goto Fail;
   1236 
   1237            args -= nargs;
   1238            if ( nargs & 1 )
   1239            {
   1240              y = ADD_LONG( y, args[0] );
   1241              args++;
   1242              nargs--;
   1243            }
   1244 
   1245            if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
   1246              goto Fail;
   1247 
   1248            while ( args < decoder->top )
   1249            {
   1250              x = ADD_LONG( x, args[0] );
   1251              cff_builder_add_point( builder, x, y, 0 );
   1252 
   1253              x = ADD_LONG( x, args[1] );
   1254              y = ADD_LONG( y, args[2] );
   1255              cff_builder_add_point( builder, x, y, 0 );
   1256 
   1257              x = ADD_LONG( x, args[3] );
   1258              cff_builder_add_point( builder, x, y, 1 );
   1259 
   1260              args += 4;
   1261            }
   1262            args = stack;
   1263          }
   1264          break;
   1265 
   1266        case cff_op_vhcurveto:
   1267        case cff_op_hvcurveto:
   1268          {
   1269            FT_Int  phase;
   1270            FT_Int  nargs;
   1271 
   1272 
   1273            FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
   1274                                                       : " hvcurveto" ));
   1275 
   1276            if ( cff_builder_start_point( builder, x, y ) )
   1277              goto Fail;
   1278 
   1279            if ( num_args < 4 )
   1280              goto Stack_Underflow;
   1281 
   1282            /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
   1283            /* we enforce it by clearing the second bit               */
   1284 
   1285            nargs = num_args & ~2;
   1286 
   1287            args -= nargs;
   1288            if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
   1289              goto Stack_Underflow;
   1290 
   1291            phase = ( op == cff_op_hvcurveto );
   1292 
   1293            while ( nargs >= 4 )
   1294            {
   1295              nargs -= 4;
   1296              if ( phase )
   1297              {
   1298                x = ADD_LONG( x, args[0] );
   1299                cff_builder_add_point( builder, x, y, 0 );
   1300 
   1301                x = ADD_LONG( x, args[1] );
   1302                y = ADD_LONG( y, args[2] );
   1303                cff_builder_add_point( builder, x, y, 0 );
   1304 
   1305                y = ADD_LONG( y, args[3] );
   1306                if ( nargs == 1 )
   1307                  x = ADD_LONG( x, args[4] );
   1308                cff_builder_add_point( builder, x, y, 1 );
   1309              }
   1310              else
   1311              {
   1312                y = ADD_LONG( y, args[0] );
   1313                cff_builder_add_point( builder, x, y, 0 );
   1314 
   1315                x = ADD_LONG( x, args[1] );
   1316                y = ADD_LONG( y, args[2] );
   1317                cff_builder_add_point( builder, x, y, 0 );
   1318 
   1319                x = ADD_LONG( x, args[3] );
   1320                if ( nargs == 1 )
   1321                  y = ADD_LONG( y, args[4] );
   1322                cff_builder_add_point( builder, x, y, 1 );
   1323              }
   1324              args  += 4;
   1325              phase ^= 1;
   1326            }
   1327            args = stack;
   1328          }
   1329          break;
   1330 
   1331        case cff_op_rlinecurve:
   1332          {
   1333            FT_Int  num_lines;
   1334            FT_Int  nargs;
   1335 
   1336 
   1337            FT_TRACE4(( " rlinecurve\n" ));
   1338 
   1339            if ( num_args < 8 )
   1340              goto Stack_Underflow;
   1341 
   1342            nargs     = num_args & ~1;
   1343            num_lines = ( nargs - 6 ) / 2;
   1344 
   1345            if ( cff_builder_start_point( builder, x, y )   ||
   1346                 cff_check_points( builder, num_lines + 3 ) )
   1347              goto Fail;
   1348 
   1349            args -= nargs;
   1350 
   1351            /* first, add the line segments */
   1352            while ( num_lines > 0 )
   1353            {
   1354              x = ADD_LONG( x, args[0] );
   1355              y = ADD_LONG( y, args[1] );
   1356              cff_builder_add_point( builder, x, y, 1 );
   1357 
   1358              args += 2;
   1359              num_lines--;
   1360            }
   1361 
   1362            /* then the curve */
   1363            x = ADD_LONG( x, args[0] );
   1364            y = ADD_LONG( y, args[1] );
   1365            cff_builder_add_point( builder, x, y, 0 );
   1366 
   1367            x = ADD_LONG( x, args[2] );
   1368            y = ADD_LONG( y, args[3] );
   1369            cff_builder_add_point( builder, x, y, 0 );
   1370 
   1371            x = ADD_LONG( x, args[4] );
   1372            y = ADD_LONG( y, args[5] );
   1373            cff_builder_add_point( builder, x, y, 1 );
   1374 
   1375            args = stack;
   1376          }
   1377          break;
   1378 
   1379        case cff_op_rcurveline:
   1380          {
   1381            FT_Int  num_curves;
   1382            FT_Int  nargs;
   1383 
   1384 
   1385            FT_TRACE4(( " rcurveline\n" ));
   1386 
   1387            if ( num_args < 8 )
   1388              goto Stack_Underflow;
   1389 
   1390            nargs      = num_args - 2;
   1391            nargs      = nargs - nargs % 6 + 2;
   1392            num_curves = ( nargs - 2 ) / 6;
   1393 
   1394            if ( cff_builder_start_point( builder, x, y )        ||
   1395                 cff_check_points( builder, num_curves * 3 + 2 ) )
   1396              goto Fail;
   1397 
   1398            args -= nargs;
   1399 
   1400            /* first, add the curves */
   1401            while ( num_curves > 0 )
   1402            {
   1403              x = ADD_LONG( x, args[0] );
   1404              y = ADD_LONG( y, args[1] );
   1405              cff_builder_add_point( builder, x, y, 0 );
   1406 
   1407              x = ADD_LONG( x, args[2] );
   1408              y = ADD_LONG( y, args[3] );
   1409              cff_builder_add_point( builder, x, y, 0 );
   1410 
   1411              x = ADD_LONG( x, args[4] );
   1412              y = ADD_LONG( y, args[5] );
   1413              cff_builder_add_point( builder, x, y, 1 );
   1414 
   1415              args += 6;
   1416              num_curves--;
   1417            }
   1418 
   1419            /* then the final line */
   1420            x = ADD_LONG( x, args[0] );
   1421            y = ADD_LONG( y, args[1] );
   1422            cff_builder_add_point( builder, x, y, 1 );
   1423 
   1424            args = stack;
   1425          }
   1426          break;
   1427 
   1428        case cff_op_hflex1:
   1429          {
   1430            FT_Pos  start_y;
   1431 
   1432 
   1433            FT_TRACE4(( " hflex1\n" ));
   1434 
   1435            /* adding five more points: 4 control points, 1 on-curve point */
   1436            /* -- make sure we have enough space for the start point if it */
   1437            /* needs to be added                                           */
   1438            if ( cff_builder_start_point( builder, x, y ) ||
   1439                 cff_check_points( builder, 6 )           )
   1440              goto Fail;
   1441 
   1442            /* record the starting point's y position for later use */
   1443            start_y = y;
   1444 
   1445            /* first control point */
   1446            x = ADD_LONG( x, args[0] );
   1447            y = ADD_LONG( y, args[1] );
   1448            cff_builder_add_point( builder, x, y, 0 );
   1449 
   1450            /* second control point */
   1451            x = ADD_LONG( x, args[2] );
   1452            y = ADD_LONG( y, args[3] );
   1453            cff_builder_add_point( builder, x, y, 0 );
   1454 
   1455            /* join point; on curve, with y-value the same as the last */
   1456            /* control point's y-value                                 */
   1457            x = ADD_LONG( x, args[4] );
   1458            cff_builder_add_point( builder, x, y, 1 );
   1459 
   1460            /* third control point, with y-value the same as the join */
   1461            /* point's y-value                                        */
   1462            x = ADD_LONG( x, args[5] );
   1463            cff_builder_add_point( builder, x, y, 0 );
   1464 
   1465            /* fourth control point */
   1466            x = ADD_LONG( x, args[6] );
   1467            y = ADD_LONG( y, args[7] );
   1468            cff_builder_add_point( builder, x, y, 0 );
   1469 
   1470            /* ending point, with y-value the same as the start   */
   1471            x = ADD_LONG( x, args[8] );
   1472            y = start_y;
   1473            cff_builder_add_point( builder, x, y, 1 );
   1474 
   1475            args = stack;
   1476            break;
   1477          }
   1478 
   1479        case cff_op_hflex:
   1480          {
   1481            FT_Pos  start_y;
   1482 
   1483 
   1484            FT_TRACE4(( " hflex\n" ));
   1485 
   1486            /* adding six more points; 4 control points, 2 on-curve points */
   1487            if ( cff_builder_start_point( builder, x, y ) ||
   1488                 cff_check_points( builder, 6 )           )
   1489              goto Fail;
   1490 
   1491            /* record the starting point's y-position for later use */
   1492            start_y = y;
   1493 
   1494            /* first control point */
   1495            x = ADD_LONG( x, args[0] );
   1496            cff_builder_add_point( builder, x, y, 0 );
   1497 
   1498            /* second control point */
   1499            x = ADD_LONG( x, args[1] );
   1500            y = ADD_LONG( y, args[2] );
   1501            cff_builder_add_point( builder, x, y, 0 );
   1502 
   1503            /* join point; on curve, with y-value the same as the last */
   1504            /* control point's y-value                                 */
   1505            x = ADD_LONG( x, args[3] );
   1506            cff_builder_add_point( builder, x, y, 1 );
   1507 
   1508            /* third control point, with y-value the same as the join */
   1509            /* point's y-value                                        */
   1510            x = ADD_LONG( x, args[4] );
   1511            cff_builder_add_point( builder, x, y, 0 );
   1512 
   1513            /* fourth control point */
   1514            x = ADD_LONG( x, args[5] );
   1515            y = start_y;
   1516            cff_builder_add_point( builder, x, y, 0 );
   1517 
   1518            /* ending point, with y-value the same as the start point's */
   1519            /* y-value -- we don't add this point, though               */
   1520            x = ADD_LONG( x, args[6] );
   1521            cff_builder_add_point( builder, x, y, 1 );
   1522 
   1523            args = stack;
   1524            break;
   1525          }
   1526 
   1527        case cff_op_flex1:
   1528          {
   1529            FT_Pos     start_x, start_y; /* record start x, y values for */
   1530                                         /* alter use                    */
   1531            FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
   1532                                         /* algorithm below              */
   1533            FT_Int     horizontal, count;
   1534            FT_Fixed*  temp;
   1535 
   1536 
   1537            FT_TRACE4(( " flex1\n" ));
   1538 
   1539            /* adding six more points; 4 control points, 2 on-curve points */
   1540            if ( cff_builder_start_point( builder, x, y ) ||
   1541                 cff_check_points( builder, 6 )           )
   1542              goto Fail;
   1543 
   1544            /* record the starting point's x, y position for later use */
   1545            start_x = x;
   1546            start_y = y;
   1547 
   1548            /* XXX: figure out whether this is supposed to be a horizontal */
   1549            /*      or vertical flex; the Type 2 specification is vague... */
   1550 
   1551            temp = args;
   1552 
   1553            /* grab up to the last argument */
   1554            for ( count = 5; count > 0; count-- )
   1555            {
   1556              dx    = ADD_LONG( dx, temp[0] );
   1557              dy    = ADD_LONG( dy, temp[1] );
   1558              temp += 2;
   1559            }
   1560 
   1561            if ( dx < 0 )
   1562              dx = NEG_LONG( dx );
   1563            if ( dy < 0 )
   1564              dy = NEG_LONG( dy );
   1565 
   1566            /* strange test, but here it is... */
   1567            horizontal = ( dx > dy );
   1568 
   1569            for ( count = 5; count > 0; count-- )
   1570            {
   1571              x = ADD_LONG( x, args[0] );
   1572              y = ADD_LONG( y, args[1] );
   1573              cff_builder_add_point( builder, x, y,
   1574                                     FT_BOOL( count == 3 ) );
   1575              args += 2;
   1576            }
   1577 
   1578            /* is last operand an x- or y-delta? */
   1579            if ( horizontal )
   1580            {
   1581              x = ADD_LONG( x, args[0] );
   1582              y = start_y;
   1583            }
   1584            else
   1585            {
   1586              x = start_x;
   1587              y = ADD_LONG( y, args[0] );
   1588            }
   1589 
   1590            cff_builder_add_point( builder, x, y, 1 );
   1591 
   1592            args = stack;
   1593            break;
   1594           }
   1595 
   1596        case cff_op_flex:
   1597          {
   1598            FT_UInt  count;
   1599 
   1600 
   1601            FT_TRACE4(( " flex\n" ));
   1602 
   1603            if ( cff_builder_start_point( builder, x, y ) ||
   1604                 cff_check_points( builder, 6 )           )
   1605              goto Fail;
   1606 
   1607            for ( count = 6; count > 0; count-- )
   1608            {
   1609              x = ADD_LONG( x, args[0] );
   1610              y = ADD_LONG( y, args[1] );
   1611              cff_builder_add_point( builder, x, y,
   1612                                     FT_BOOL( count == 4 || count == 1 ) );
   1613              args += 2;
   1614            }
   1615 
   1616            args = stack;
   1617          }
   1618          break;
   1619 
   1620        case cff_op_seac:
   1621          FT_TRACE4(( " seac\n" ));
   1622 
   1623          error = cff_operator_seac( decoder,
   1624                                     args[0], args[1], args[2],
   1625                                     (FT_Int)( args[3] >> 16 ),
   1626                                     (FT_Int)( args[4] >> 16 ) );
   1627 
   1628          /* add current outline to the glyph slot */
   1629          FT_GlyphLoader_Add( builder->loader );
   1630 
   1631          /* return now! */
   1632          FT_TRACE4(( "\n" ));
   1633          return error;
   1634 
   1635        case cff_op_endchar:
   1636          /* in dictionaries, `endchar' simply indicates end of data */
   1637          if ( in_dict )
   1638            return error;
   1639 
   1640          FT_TRACE4(( " endchar\n" ));
   1641 
   1642          /* We are going to emulate the seac operator. */
   1643          if ( num_args >= 4 )
   1644          {
   1645            /* Save glyph width so that the subglyphs don't overwrite it. */
   1646            FT_Pos  glyph_width = decoder->glyph_width;
   1647 
   1648 
   1649            error = cff_operator_seac( decoder,
   1650                                       0L, args[-4], args[-3],
   1651                                       (FT_Int)( args[-2] >> 16 ),
   1652                                       (FT_Int)( args[-1] >> 16 ) );
   1653 
   1654            decoder->glyph_width = glyph_width;
   1655          }
   1656          else
   1657          {
   1658            cff_builder_close_contour( builder );
   1659 
   1660            /* close hints recording session */
   1661            if ( hinter )
   1662            {
   1663              if ( hinter->close( hinter->hints,
   1664                                  (FT_UInt)builder->current->n_points ) )
   1665                goto Syntax_Error;
   1666 
   1667              /* apply hints to the loaded glyph outline now */
   1668              error = hinter->apply( hinter->hints,
   1669                                     builder->current,
   1670                                     (PSH_Globals)builder->hints_globals,
   1671                                     decoder->hint_mode );
   1672              if ( error )
   1673                goto Fail;
   1674            }
   1675 
   1676            /* add current outline to the glyph slot */
   1677            FT_GlyphLoader_Add( builder->loader );
   1678          }
   1679 
   1680          /* return now! */
   1681          FT_TRACE4(( "\n" ));
   1682          return error;
   1683 
   1684        case cff_op_abs:
   1685          FT_TRACE4(( " abs\n" ));
   1686 
   1687          if ( args[0] < 0 )
   1688          {
   1689            if ( args[0] == FT_LONG_MIN )
   1690              args[0] = FT_LONG_MAX;
   1691            else
   1692              args[0] = -args[0];
   1693          }
   1694          args++;
   1695          break;
   1696 
   1697        case cff_op_add:
   1698          FT_TRACE4(( " add\n" ));
   1699 
   1700          args[0] = ADD_LONG( args[0], args[1] );
   1701          args++;
   1702          break;
   1703 
   1704        case cff_op_sub:
   1705          FT_TRACE4(( " sub\n" ));
   1706 
   1707          args[0] = SUB_LONG( args[0], args[1] );
   1708          args++;
   1709          break;
   1710 
   1711        case cff_op_div:
   1712          FT_TRACE4(( " div\n" ));
   1713 
   1714          args[0] = FT_DivFix( args[0], args[1] );
   1715          args++;
   1716          break;
   1717 
   1718        case cff_op_neg:
   1719          FT_TRACE4(( " neg\n" ));
   1720 
   1721          if ( args[0] == FT_LONG_MIN )
   1722            args[0] = FT_LONG_MAX;
   1723          args[0] = -args[0];
   1724          args++;
   1725          break;
   1726 
   1727        case cff_op_random:
   1728          {
   1729            FT_UInt32*  randval = in_dict ? &decoder->cff->top_font.random
   1730                                          : &decoder->current_subfont->random;
   1731 
   1732 
   1733            FT_TRACE4(( " random\n" ));
   1734 
   1735            /* only use the lower 16 bits of `random'  */
   1736            /* to generate a number in the range (0;1] */
   1737            args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
   1738            args++;
   1739 
   1740            *randval = cff_random( *randval );
   1741          }
   1742          break;
   1743 
   1744        case cff_op_mul:
   1745          FT_TRACE4(( " mul\n" ));
   1746 
   1747          args[0] = FT_MulFix( args[0], args[1] );
   1748          args++;
   1749          break;
   1750 
   1751        case cff_op_sqrt:
   1752          FT_TRACE4(( " sqrt\n" ));
   1753 
   1754          /* without upper limit the loop below might not finish */
   1755          if ( args[0] > 0x7FFFFFFFL )
   1756            args[0] = 0xB504F4L;    /* sqrt( 32768.0044 ) */
   1757          else if ( args[0] > 0 )
   1758            args[0] = (FT_Fixed)FT_SqrtFixed( args[0] );
   1759          else
   1760            args[0] = 0;
   1761          args++;
   1762          break;
   1763 
   1764        case cff_op_drop:
   1765          /* nothing */
   1766          FT_TRACE4(( " drop\n" ));
   1767 
   1768          break;
   1769 
   1770        case cff_op_exch:
   1771          {
   1772            FT_Fixed  tmp;
   1773 
   1774 
   1775            FT_TRACE4(( " exch\n" ));
   1776 
   1777            tmp     = args[0];
   1778            args[0] = args[1];
   1779            args[1] = tmp;
   1780            args   += 2;
   1781          }
   1782          break;
   1783 
   1784        case cff_op_index:
   1785          {
   1786            FT_Int  idx = (FT_Int)( args[0] >> 16 );
   1787 
   1788 
   1789            FT_TRACE4(( " index\n" ));
   1790 
   1791            if ( idx < 0 )
   1792              idx = 0;
   1793            else if ( idx > num_args - 2 )
   1794              idx = num_args - 2;
   1795            args[0] = args[-( idx + 1 )];
   1796            args++;
   1797          }
   1798          break;
   1799 
   1800        case cff_op_roll:
   1801          {
   1802            FT_Int  count = (FT_Int)( args[0] >> 16 );
   1803            FT_Int  idx   = (FT_Int)( args[1] >> 16 );
   1804 
   1805 
   1806            FT_TRACE4(( " roll\n" ));
   1807 
   1808            if ( count <= 0 )
   1809              count = 1;
   1810 
   1811            args -= count;
   1812            if ( args < stack )
   1813              goto Stack_Underflow;
   1814 
   1815            if ( idx >= 0 )
   1816            {
   1817              idx = idx % count;
   1818              while ( idx > 0 )
   1819              {
   1820                FT_Fixed  tmp = args[count - 1];
   1821                FT_Int    i;
   1822 
   1823 
   1824                for ( i = count - 2; i >= 0; i-- )
   1825                  args[i + 1] = args[i];
   1826                args[0] = tmp;
   1827                idx--;
   1828              }
   1829            }
   1830            else
   1831            {
   1832              /* before C99 it is implementation-defined whether    */
   1833              /* the result of `%' is negative if the first operand */
   1834              /* is negative                                        */
   1835              idx = -( NEG_INT( idx ) % count );
   1836              while ( idx < 0 )
   1837              {
   1838                FT_Fixed  tmp = args[0];
   1839                FT_Int    i;
   1840 
   1841 
   1842                for ( i = 0; i < count - 1; i++ )
   1843                  args[i] = args[i + 1];
   1844                args[count - 1] = tmp;
   1845                idx++;
   1846              }
   1847            }
   1848            args += count;
   1849          }
   1850          break;
   1851 
   1852        case cff_op_dup:
   1853          FT_TRACE4(( " dup\n" ));
   1854 
   1855          args[1] = args[0];
   1856          args   += 2;
   1857          break;
   1858 
   1859        case cff_op_put:
   1860          {
   1861            FT_Fixed  val = args[0];
   1862            FT_UInt   idx = (FT_UInt)( args[1] >> 16 );
   1863 
   1864 
   1865            FT_TRACE4(( " put\n" ));
   1866 
   1867            /* the Type2 specification before version 16-March-2000 */
   1868            /* didn't give a hard-coded size limit of the temporary */
   1869            /* storage array; instead, an argument of the           */
   1870            /* `MultipleMaster' operator set the size               */
   1871            if ( idx < CFF_MAX_TRANS_ELEMENTS )
   1872              decoder->buildchar[idx] = val;
   1873          }
   1874          break;
   1875 
   1876        case cff_op_get:
   1877          {
   1878            FT_UInt   idx = (FT_UInt)( args[0] >> 16 );
   1879            FT_Fixed  val = 0;
   1880 
   1881 
   1882            FT_TRACE4(( " get\n" ));
   1883 
   1884            if ( idx < CFF_MAX_TRANS_ELEMENTS )
   1885              val = decoder->buildchar[idx];
   1886 
   1887            args[0] = val;
   1888            args++;
   1889          }
   1890          break;
   1891 
   1892        case cff_op_store:
   1893          /* this operator was removed from the Type2 specification */
   1894          /* in version 16-March-2000                               */
   1895 
   1896          /* since we currently don't handle interpolation of multiple */
   1897          /* master fonts, this is a no-op                             */
   1898          FT_TRACE4(( " store\n" ));
   1899          break;
   1900 
   1901        case cff_op_load:
   1902          /* this operator was removed from the Type2 specification */
   1903          /* in version 16-March-2000                               */
   1904          {
   1905            FT_UInt  reg_idx = (FT_UInt)args[0];
   1906            FT_UInt  idx     = (FT_UInt)args[1];
   1907            FT_UInt  count   = (FT_UInt)args[2];
   1908 
   1909 
   1910            FT_TRACE4(( " load\n" ));
   1911 
   1912            /* since we currently don't handle interpolation of multiple */
   1913            /* master fonts, we store a vector [1 0 0 ...] in the        */
   1914            /* temporary storage array regardless of the Registry index  */
   1915            if ( reg_idx <= 2                 &&
   1916                 idx < CFF_MAX_TRANS_ELEMENTS &&
   1917                 count <= num_axes            )
   1918            {
   1919              FT_UInt  end, i;
   1920 
   1921 
   1922              end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
   1923 
   1924              if ( idx < end )
   1925                decoder->buildchar[idx] = 1 << 16;
   1926 
   1927              for ( i = idx + 1; i < end; i++ )
   1928                decoder->buildchar[i] = 0;
   1929            }
   1930          }
   1931          break;
   1932 
   1933        case cff_op_blend:
   1934          /* this operator was removed from the Type2 specification */
   1935          /* in version 16-March-2000                               */
   1936          if ( num_designs )
   1937          {
   1938            FT_Int  num_results = (FT_Int)( args[0] >> 16 );
   1939 
   1940 
   1941            FT_TRACE4(( " blend\n" ));
   1942 
   1943            if ( num_results < 0 )
   1944              goto Syntax_Error;
   1945 
   1946            if ( num_results > num_args                       ||
   1947                 num_results * (FT_Int)num_designs > num_args )
   1948              goto Stack_Underflow;
   1949 
   1950            /* since we currently don't handle interpolation of multiple */
   1951            /* master fonts, return the `num_results' values of the      */
   1952            /* first master                                              */
   1953            args     -= num_results * ( num_designs - 1 );
   1954            num_args -= num_results * ( num_designs - 1 );
   1955          }
   1956          else
   1957            goto Syntax_Error;
   1958          break;
   1959 
   1960        case cff_op_dotsection:
   1961          /* this operator is deprecated and ignored by the parser */
   1962          FT_TRACE4(( " dotsection\n" ));
   1963          break;
   1964 
   1965        case cff_op_closepath:
   1966          /* this is an invalid Type 2 operator; however, there        */
   1967          /* exist fonts which are incorrectly converted from probably */
   1968          /* Type 1 to CFF, and some parsers seem to accept it         */
   1969 
   1970          FT_TRACE4(( " closepath (invalid op)\n" ));
   1971 
   1972          args = stack;
   1973          break;
   1974 
   1975        case cff_op_hsbw:
   1976          /* this is an invalid Type 2 operator; however, there        */
   1977          /* exist fonts which are incorrectly converted from probably */
   1978          /* Type 1 to CFF, and some parsers seem to accept it         */
   1979 
   1980          FT_TRACE4(( " hsbw (invalid op)\n" ));
   1981 
   1982          decoder->glyph_width =
   1983            ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
   1984 
   1985          decoder->builder.left_bearing.x = args[0];
   1986          decoder->builder.left_bearing.y = 0;
   1987 
   1988          x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   1989          y    = decoder->builder.pos_y;
   1990          args = stack;
   1991          break;
   1992 
   1993        case cff_op_sbw:
   1994          /* this is an invalid Type 2 operator; however, there        */
   1995          /* exist fonts which are incorrectly converted from probably */
   1996          /* Type 1 to CFF, and some parsers seem to accept it         */
   1997 
   1998          FT_TRACE4(( " sbw (invalid op)\n" ));
   1999 
   2000          decoder->glyph_width =
   2001            ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
   2002 
   2003          decoder->builder.left_bearing.x = args[0];
   2004          decoder->builder.left_bearing.y = args[1];
   2005 
   2006          x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   2007          y    = ADD_LONG( decoder->builder.pos_y, args[1] );
   2008          args = stack;
   2009          break;
   2010 
   2011        case cff_op_setcurrentpoint:
   2012          /* this is an invalid Type 2 operator; however, there        */
   2013          /* exist fonts which are incorrectly converted from probably */
   2014          /* Type 1 to CFF, and some parsers seem to accept it         */
   2015 
   2016          FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
   2017 
   2018          x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   2019          y    = ADD_LONG( decoder->builder.pos_y, args[1] );
   2020          args = stack;
   2021          break;
   2022 
   2023        case cff_op_callothersubr:
   2024          {
   2025            FT_Fixed  arg;
   2026 
   2027 
   2028            /* this is an invalid Type 2 operator; however, there      */
   2029            /* exist fonts which are incorrectly converted from        */
   2030            /* probably Type 1 to CFF, and some parsers seem to accept */
   2031            /* it                                                      */
   2032 
   2033            FT_TRACE4(( " callothersubr (invalid op)\n" ));
   2034 
   2035            /* subsequent `pop' operands should add the arguments,     */
   2036            /* this is the implementation described for `unknown'      */
   2037            /* other subroutines in the Type1 spec.                    */
   2038            /*                                                         */
   2039            /* XXX Fix return arguments (see discussion below).        */
   2040 
   2041            arg = 2 + ( args[-2] >> 16 );
   2042            if ( arg >= CFF_MAX_OPERANDS )
   2043              goto Stack_Underflow;
   2044 
   2045            args -= arg;
   2046            if ( args < stack )
   2047              goto Stack_Underflow;
   2048          }
   2049          break;
   2050 
   2051        case cff_op_pop:
   2052          /* this is an invalid Type 2 operator; however, there        */
   2053          /* exist fonts which are incorrectly converted from probably */
   2054          /* Type 1 to CFF, and some parsers seem to accept it         */
   2055 
   2056          FT_TRACE4(( " pop (invalid op)\n" ));
   2057 
   2058          /* XXX Increasing `args' is wrong: After a certain number of */
   2059          /* `pop's we get a stack overflow.  Reason for doing it is   */
   2060          /* code like this (actually found in a CFF font):            */
   2061          /*                                                           */
   2062          /*   17 1 3 callothersubr                                    */
   2063          /*   pop                                                     */
   2064          /*   callsubr                                                */
   2065          /*                                                           */
   2066          /* Since we handle `callothersubr' as a no-op, and           */
   2067          /* `callsubr' needs at least one argument, `pop' can't be a  */
   2068          /* no-op too as it basically should be.                      */
   2069          /*                                                           */
   2070          /* The right solution would be to provide real support for   */
   2071          /* `callothersubr' as done in `t1decode.c', however, given   */
   2072          /* the fact that CFF fonts with `pop' are invalid, it is     */
   2073          /* questionable whether it is worth the time.                */
   2074          args++;
   2075          break;
   2076 
   2077        case cff_op_and:
   2078          {
   2079            FT_Fixed  cond = ( args[0] && args[1] );
   2080 
   2081 
   2082            FT_TRACE4(( " and\n" ));
   2083 
   2084            args[0] = cond ? 0x10000L : 0;
   2085            args++;
   2086          }
   2087          break;
   2088 
   2089        case cff_op_or:
   2090          {
   2091            FT_Fixed  cond = ( args[0] || args[1] );
   2092 
   2093 
   2094            FT_TRACE4(( " or\n" ));
   2095 
   2096            args[0] = cond ? 0x10000L : 0;
   2097            args++;
   2098          }
   2099          break;
   2100 
   2101        case cff_op_not:
   2102          {
   2103            FT_Fixed  cond = !args[0];
   2104 
   2105 
   2106            FT_TRACE4(( " not\n" ));
   2107 
   2108            args[0] = cond ? 0x10000L : 0;
   2109            args++;
   2110          }
   2111          break;
   2112 
   2113        case cff_op_eq:
   2114          {
   2115            FT_Fixed  cond = ( args[0] == args[1] );
   2116 
   2117 
   2118            FT_TRACE4(( " eq\n" ));
   2119 
   2120            args[0] = cond ? 0x10000L : 0;
   2121            args++;
   2122          }
   2123          break;
   2124 
   2125        case cff_op_ifelse:
   2126          {
   2127            FT_Fixed  cond = ( args[2] <= args[3] );
   2128 
   2129 
   2130            FT_TRACE4(( " ifelse\n" ));
   2131 
   2132            if ( !cond )
   2133              args[0] = args[1];
   2134            args++;
   2135          }
   2136          break;
   2137 
   2138        case cff_op_callsubr:
   2139          {
   2140            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
   2141                                      decoder->locals_bias );
   2142 
   2143 
   2144            FT_TRACE4(( " callsubr (idx %u, entering level %td)\n",
   2145                        idx,
   2146                        zone - decoder->zones + 1 ));
   2147 
   2148            if ( idx >= decoder->num_locals )
   2149            {
   2150              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2151                         " invalid local subr index\n" ));
   2152              goto Syntax_Error;
   2153            }
   2154 
   2155            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
   2156            {
   2157              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2158                         " too many nested subrs\n" ));
   2159              goto Syntax_Error;
   2160            }
   2161 
   2162            zone->cursor = ip;  /* save current instruction pointer */
   2163 
   2164            zone++;
   2165            zone->base   = decoder->locals[idx];
   2166            zone->limit  = decoder->locals[idx + 1];
   2167            zone->cursor = zone->base;
   2168 
   2169            if ( !zone->base || zone->limit == zone->base )
   2170            {
   2171              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2172                         " invoking empty subrs\n" ));
   2173              goto Syntax_Error;
   2174            }
   2175 
   2176            decoder->zone = zone;
   2177            ip            = zone->base;
   2178            limit         = zone->limit;
   2179          }
   2180          break;
   2181 
   2182        case cff_op_callgsubr:
   2183          {
   2184            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
   2185                                      decoder->globals_bias );
   2186 
   2187 
   2188            FT_TRACE4(( " callgsubr (idx %u, entering level %td)\n",
   2189                        idx,
   2190                        zone - decoder->zones + 1 ));
   2191 
   2192            if ( idx >= decoder->num_globals )
   2193            {
   2194              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2195                         " invalid global subr index\n" ));
   2196              goto Syntax_Error;
   2197            }
   2198 
   2199            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
   2200            {
   2201              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2202                         " too many nested subrs\n" ));
   2203              goto Syntax_Error;
   2204            }
   2205 
   2206            zone->cursor = ip;  /* save current instruction pointer */
   2207 
   2208            zone++;
   2209            zone->base   = decoder->globals[idx];
   2210            zone->limit  = decoder->globals[idx + 1];
   2211            zone->cursor = zone->base;
   2212 
   2213            if ( !zone->base || zone->limit == zone->base )
   2214            {
   2215              FT_ERROR(( "cff_decoder_parse_charstrings:"
   2216                         " invoking empty subrs\n" ));
   2217              goto Syntax_Error;
   2218            }
   2219 
   2220            decoder->zone = zone;
   2221            ip            = zone->base;
   2222            limit         = zone->limit;
   2223          }
   2224          break;
   2225 
   2226        case cff_op_return:
   2227          FT_TRACE4(( " return (leaving level %td)\n",
   2228                      decoder->zone - decoder->zones ));
   2229 
   2230          if ( decoder->zone <= decoder->zones )
   2231          {
   2232            FT_ERROR(( "cff_decoder_parse_charstrings:"
   2233                       " unexpected return\n" ));
   2234            goto Syntax_Error;
   2235          }
   2236 
   2237          decoder->zone--;
   2238          zone  = decoder->zone;
   2239          ip    = zone->cursor;
   2240          limit = zone->limit;
   2241          break;
   2242 
   2243        default:
   2244          FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
   2245 
   2246          if ( ip[-1] == 12 )
   2247            FT_ERROR(( " %d", ip[0] ));
   2248          FT_ERROR(( "\n" ));
   2249 
   2250          return FT_THROW( Unimplemented_Feature );
   2251        }
   2252 
   2253        decoder->top = args;
   2254 
   2255        if ( decoder->top - stack >= CFF_MAX_OPERANDS )
   2256          goto Stack_Overflow;
   2257 
   2258      } /* general operator processing */
   2259 
   2260    } /* while ip < limit */
   2261 
   2262    FT_TRACE4(( "..end..\n" ));
   2263    FT_TRACE4(( "\n" ));
   2264 
   2265  Fail:
   2266    return error;
   2267 
   2268  MM_Error:
   2269    FT_TRACE4(( "cff_decoder_parse_charstrings:"
   2270                " invalid opcode found in top DICT charstring\n"));
   2271    return FT_THROW( Invalid_File_Format );
   2272 
   2273  Syntax_Error:
   2274    FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
   2275    return FT_THROW( Invalid_File_Format );
   2276 
   2277  Stack_Underflow:
   2278    FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
   2279    return FT_THROW( Too_Few_Arguments );
   2280 
   2281  Stack_Overflow:
   2282    FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
   2283    return FT_THROW( Stack_Overflow );
   2284  }
   2285 
   2286 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   2287 
   2288 
   2289  /**************************************************************************
   2290   *
   2291   * @Function:
   2292   *   cff_decoder_init
   2293   *
   2294   * @Description:
   2295   *   Initializes a given glyph decoder.
   2296   *
   2297   * @InOut:
   2298   *   decoder ::
   2299   *     A pointer to the glyph builder to initialize.
   2300   *
   2301   * @Input:
   2302   *   face ::
   2303   *     The current face object.
   2304   *
   2305   *   size ::
   2306   *     The current size object.
   2307   *
   2308   *   slot ::
   2309   *     The current glyph object.
   2310   *
   2311   *   hinting ::
   2312   *     Whether hinting is active.
   2313   *
   2314   *   hint_mode ::
   2315   *     The hinting mode.
   2316   */
   2317  FT_LOCAL_DEF( void )
   2318  cff_decoder_init( CFF_Decoder*                     decoder,
   2319                    TT_Face                          face,
   2320                    CFF_Size                         size,
   2321                    CFF_GlyphSlot                    slot,
   2322                    FT_Bool                          hinting,
   2323                    FT_Render_Mode                   hint_mode,
   2324                    CFF_Decoder_Get_Glyph_Callback   get_callback,
   2325                    CFF_Decoder_Free_Glyph_Callback  free_callback )
   2326  {
   2327    CFF_Font  cff = (CFF_Font)face->extra.data;
   2328 
   2329 
   2330    /* clear everything */
   2331    FT_ZERO( decoder );
   2332 
   2333    /* initialize builder */
   2334    cff_builder_init( &decoder->builder, face, size, slot, hinting );
   2335 
   2336    /* initialize Type2 decoder */
   2337    decoder->cff          = cff;
   2338    decoder->num_globals  = cff->global_subrs_index.count;
   2339    decoder->globals      = cff->global_subrs;
   2340    decoder->globals_bias = cff_compute_bias(
   2341                              cff->top_font.font_dict.charstring_type,
   2342                              decoder->num_globals );
   2343 
   2344    decoder->hint_mode = hint_mode;
   2345 
   2346    decoder->get_glyph_callback  = get_callback;
   2347    decoder->free_glyph_callback = free_callback;
   2348  }
   2349 
   2350 
   2351  /* this function is used to select the subfont */
   2352  /* and the locals subrs array                  */
   2353  FT_LOCAL_DEF( FT_Error )
   2354  cff_decoder_prepare( CFF_Decoder*  decoder,
   2355                       CFF_Size      size,
   2356                       FT_UInt       glyph_index )
   2357  {
   2358    CFF_Builder  *builder = &decoder->builder;
   2359    CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
   2360    CFF_SubFont   sub     = &cff->top_font;
   2361    FT_Error      error   = FT_Err_Ok;
   2362 
   2363    FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)cff->cffload;
   2364 
   2365 
   2366    /* manage CID fonts */
   2367    if ( cff->num_subfonts )
   2368    {
   2369      FT_Byte  fd_index = cffload->fd_select_get( &cff->fd_select,
   2370                                                  glyph_index );
   2371 
   2372 
   2373      if ( fd_index >= cff->num_subfonts )
   2374      {
   2375        FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
   2376        error = FT_THROW( Invalid_File_Format );
   2377        goto Exit;
   2378      }
   2379 
   2380      FT_TRACE3(( "  in subfont %d:\n", fd_index ));
   2381 
   2382      sub = cff->subfonts[fd_index];
   2383 
   2384      if ( builder->hints_funcs && size )
   2385      {
   2386        FT_Size       ftsize   = FT_SIZE( size );
   2387        CFF_Internal  internal = (CFF_Internal)ftsize->internal->module_data;
   2388 
   2389 
   2390        /* for CFFs without subfonts, this value has already been set */
   2391        builder->hints_globals = (void *)internal->subfonts[fd_index];
   2392      }
   2393    }
   2394 
   2395    decoder->num_locals  = sub->local_subrs_index.count;
   2396    decoder->locals      = sub->local_subrs;
   2397    decoder->locals_bias = cff_compute_bias(
   2398                             decoder->cff->top_font.font_dict.charstring_type,
   2399                             decoder->num_locals );
   2400 
   2401    decoder->glyph_width   = sub->private_dict.default_width;
   2402    decoder->nominal_width = sub->private_dict.nominal_width;
   2403 
   2404    decoder->current_subfont = sub;
   2405 
   2406  Exit:
   2407    return error;
   2408  }
   2409 
   2410 
   2411 /* END */