Home | History | Annotate | Download | only in psaux
      1 /****************************************************************************
      2  *
      3  * cffdecode.c
      4  *
      5  *   PostScript CFF (Type 2) decoding routines (body).
      6  *
      7  * Copyright 2017-2018 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 <ft2build.h>
     20 #include FT_FREETYPE_H
     21 #include FT_INTERNAL_DEBUG_H
     22 #include FT_INTERNAL_SERVICE_H
     23 #include FT_SERVICE_CFF_TABLE_LOAD_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  trace_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 += decoder->builder.left_bearing.x;
    239     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 = 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     zone->base           = charstring_base;
    534     limit = zone->limit  = charstring_base + charstring_len;
    535     ip    = zone->cursor = zone->base;
    536 
    537     error = FT_Err_Ok;
    538 
    539     x = builder->pos_x;
    540     y = builder->pos_y;
    541 
    542     /* begin hints recording session, if any */
    543     if ( hinter )
    544       hinter->open( hinter->hints );
    545 
    546     /* now execute loop */
    547     while ( ip < limit )
    548     {
    549       CFF_Operator  op;
    550       FT_Byte       v;
    551 
    552 
    553       /*********************************************************************
    554        *
    555        * Decode operator or operand
    556        */
    557       v = *ip++;
    558       if ( v >= 32 || v == 28 )
    559       {
    560         FT_Int    shift = 16;
    561         FT_Int32  val;
    562 
    563 
    564         /* this is an operand, push it on the stack */
    565 
    566         /* if we use shifts, all computations are done with unsigned */
    567         /* values; the conversion to a signed value is the last step */
    568         if ( v == 28 )
    569         {
    570           if ( ip + 1 >= limit )
    571             goto Syntax_Error;
    572           val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
    573           ip += 2;
    574         }
    575         else if ( v < 247 )
    576           val = (FT_Int32)v - 139;
    577         else if ( v < 251 )
    578         {
    579           if ( ip >= limit )
    580             goto Syntax_Error;
    581           val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
    582         }
    583         else if ( v < 255 )
    584         {
    585           if ( ip >= limit )
    586             goto Syntax_Error;
    587           val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
    588         }
    589         else
    590         {
    591           if ( ip + 3 >= limit )
    592             goto Syntax_Error;
    593           val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
    594                             ( (FT_UInt32)ip[1] << 16 ) |
    595                             ( (FT_UInt32)ip[2] <<  8 ) |
    596                               (FT_UInt32)ip[3]         );
    597           ip += 4;
    598           if ( charstring_type == 2 )
    599             shift = 0;
    600         }
    601         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
    602           goto Stack_Overflow;
    603 
    604         val             = (FT_Int32)( (FT_UInt32)val << shift );
    605         *decoder->top++ = val;
    606 
    607 #ifdef FT_DEBUG_LEVEL_TRACE
    608         if ( !( val & 0xFFFFL ) )
    609           FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
    610         else
    611           FT_TRACE4(( " %.5f", val / 65536.0 ));
    612 #endif
    613 
    614       }
    615       else
    616       {
    617         /* The specification says that normally arguments are to be taken */
    618         /* from the bottom of the stack.  However, this seems not to be   */
    619         /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
    620         /* arguments similar to a PS interpreter.                         */
    621 
    622         FT_Fixed*  args     = decoder->top;
    623         FT_Int     num_args = (FT_Int)( args - decoder->stack );
    624         FT_Int     req_args;
    625 
    626 
    627         /* find operator */
    628         op = cff_op_unknown;
    629 
    630         switch ( v )
    631         {
    632         case 1:
    633           op = cff_op_hstem;
    634           break;
    635         case 3:
    636           op = cff_op_vstem;
    637           break;
    638         case 4:
    639           op = cff_op_vmoveto;
    640           break;
    641         case 5:
    642           op = cff_op_rlineto;
    643           break;
    644         case 6:
    645           op = cff_op_hlineto;
    646           break;
    647         case 7:
    648           op = cff_op_vlineto;
    649           break;
    650         case 8:
    651           op = cff_op_rrcurveto;
    652           break;
    653         case 9:
    654           op = cff_op_closepath;
    655           break;
    656         case 10:
    657           op = cff_op_callsubr;
    658           break;
    659         case 11:
    660           op = cff_op_return;
    661           break;
    662         case 12:
    663           if ( ip >= limit )
    664             goto Syntax_Error;
    665           v = *ip++;
    666 
    667           switch ( v )
    668           {
    669           case 0:
    670             op = cff_op_dotsection;
    671             break;
    672           case 1: /* this is actually the Type1 vstem3 operator */
    673             op = cff_op_vstem;
    674             break;
    675           case 2: /* this is actually the Type1 hstem3 operator */
    676             op = cff_op_hstem;
    677             break;
    678           case 3:
    679             op = cff_op_and;
    680             break;
    681           case 4:
    682             op = cff_op_or;
    683             break;
    684           case 5:
    685             op = cff_op_not;
    686             break;
    687           case 6:
    688             op = cff_op_seac;
    689             break;
    690           case 7:
    691             op = cff_op_sbw;
    692             break;
    693           case 8:
    694             op = cff_op_store;
    695             break;
    696           case 9:
    697             op = cff_op_abs;
    698             break;
    699           case 10:
    700             op = cff_op_add;
    701             break;
    702           case 11:
    703             op = cff_op_sub;
    704             break;
    705           case 12:
    706             op = cff_op_div;
    707             break;
    708           case 13:
    709             op = cff_op_load;
    710             break;
    711           case 14:
    712             op = cff_op_neg;
    713             break;
    714           case 15:
    715             op = cff_op_eq;
    716             break;
    717           case 16:
    718             op = cff_op_callothersubr;
    719             break;
    720           case 17:
    721             op = cff_op_pop;
    722             break;
    723           case 18:
    724             op = cff_op_drop;
    725             break;
    726           case 20:
    727             op = cff_op_put;
    728             break;
    729           case 21:
    730             op = cff_op_get;
    731             break;
    732           case 22:
    733             op = cff_op_ifelse;
    734             break;
    735           case 23:
    736             op = cff_op_random;
    737             break;
    738           case 24:
    739             op = cff_op_mul;
    740             break;
    741           case 26:
    742             op = cff_op_sqrt;
    743             break;
    744           case 27:
    745             op = cff_op_dup;
    746             break;
    747           case 28:
    748             op = cff_op_exch;
    749             break;
    750           case 29:
    751             op = cff_op_index;
    752             break;
    753           case 30:
    754             op = cff_op_roll;
    755             break;
    756           case 33:
    757             op = cff_op_setcurrentpoint;
    758             break;
    759           case 34:
    760             op = cff_op_hflex;
    761             break;
    762           case 35:
    763             op = cff_op_flex;
    764             break;
    765           case 36:
    766             op = cff_op_hflex1;
    767             break;
    768           case 37:
    769             op = cff_op_flex1;
    770             break;
    771           default:
    772             FT_TRACE4(( " unknown op (12, %d)\n", v ));
    773             break;
    774           }
    775           break;
    776         case 13:
    777           op = cff_op_hsbw;
    778           break;
    779         case 14:
    780           op = cff_op_endchar;
    781           break;
    782         case 16:
    783           op = cff_op_blend;
    784           break;
    785         case 18:
    786           op = cff_op_hstemhm;
    787           break;
    788         case 19:
    789           op = cff_op_hintmask;
    790           break;
    791         case 20:
    792           op = cff_op_cntrmask;
    793           break;
    794         case 21:
    795           op = cff_op_rmoveto;
    796           break;
    797         case 22:
    798           op = cff_op_hmoveto;
    799           break;
    800         case 23:
    801           op = cff_op_vstemhm;
    802           break;
    803         case 24:
    804           op = cff_op_rcurveline;
    805           break;
    806         case 25:
    807           op = cff_op_rlinecurve;
    808           break;
    809         case 26:
    810           op = cff_op_vvcurveto;
    811           break;
    812         case 27:
    813           op = cff_op_hhcurveto;
    814           break;
    815         case 29:
    816           op = cff_op_callgsubr;
    817           break;
    818         case 30:
    819           op = cff_op_vhcurveto;
    820           break;
    821         case 31:
    822           op = cff_op_hvcurveto;
    823           break;
    824         default:
    825           FT_TRACE4(( " unknown op (%d)\n", v ));
    826           break;
    827         }
    828 
    829         if ( op == cff_op_unknown )
    830           continue;
    831 
    832         /* in Multiple Master CFFs, T2 charstrings can appear in */
    833         /* dictionaries, but some operators are prohibited       */
    834         if ( in_dict )
    835         {
    836           switch ( op )
    837           {
    838           case cff_op_hstem:
    839           case cff_op_vstem:
    840           case cff_op_vmoveto:
    841           case cff_op_rlineto:
    842           case cff_op_hlineto:
    843           case cff_op_vlineto:
    844           case cff_op_rrcurveto:
    845           case cff_op_hstemhm:
    846           case cff_op_hintmask:
    847           case cff_op_cntrmask:
    848           case cff_op_rmoveto:
    849           case cff_op_hmoveto:
    850           case cff_op_vstemhm:
    851           case cff_op_rcurveline:
    852           case cff_op_rlinecurve:
    853           case cff_op_vvcurveto:
    854           case cff_op_hhcurveto:
    855           case cff_op_vhcurveto:
    856           case cff_op_hvcurveto:
    857           case cff_op_hflex:
    858           case cff_op_flex:
    859           case cff_op_hflex1:
    860           case cff_op_flex1:
    861           case cff_op_callsubr:
    862           case cff_op_callgsubr:
    863             goto MM_Error;
    864 
    865           default:
    866             break;
    867           }
    868         }
    869 
    870         /* check arguments */
    871         req_args = cff_argument_counts[op];
    872         if ( req_args & CFF_COUNT_CHECK_WIDTH )
    873         {
    874           if ( num_args > 0 && decoder->read_width )
    875           {
    876             /* If `nominal_width' is non-zero, the number is really a      */
    877             /* difference against `nominal_width'.  Else, the number here  */
    878             /* is truly a width, not a difference against `nominal_width'. */
    879             /* If the font does not set `nominal_width', then              */
    880             /* `nominal_width' defaults to zero, and so we can set         */
    881             /* `glyph_width' to `nominal_width' plus number on the stack   */
    882             /* -- for either case.                                         */
    883 
    884             FT_Int  set_width_ok;
    885 
    886 
    887             switch ( op )
    888             {
    889             case cff_op_hmoveto:
    890             case cff_op_vmoveto:
    891               set_width_ok = num_args & 2;
    892               break;
    893 
    894             case cff_op_hstem:
    895             case cff_op_vstem:
    896             case cff_op_hstemhm:
    897             case cff_op_vstemhm:
    898             case cff_op_rmoveto:
    899             case cff_op_hintmask:
    900             case cff_op_cntrmask:
    901               set_width_ok = num_args & 1;
    902               break;
    903 
    904             case cff_op_endchar:
    905               /* If there is a width specified for endchar, we either have */
    906               /* 1 argument or 5 arguments.  We like to argue.             */
    907               set_width_ok = in_dict
    908                                ? 0
    909                                : ( ( num_args == 5 ) || ( num_args == 1 ) );
    910               break;
    911 
    912             default:
    913               set_width_ok = 0;
    914               break;
    915             }
    916 
    917             if ( set_width_ok )
    918             {
    919               decoder->glyph_width = decoder->nominal_width +
    920                                        ( stack[0] >> 16 );
    921 
    922               if ( decoder->width_only )
    923               {
    924                 /* we only want the advance width; stop here */
    925                 break;
    926               }
    927 
    928               /* Consumed an argument. */
    929               num_args--;
    930             }
    931           }
    932 
    933           decoder->read_width = 0;
    934           req_args            = 0;
    935         }
    936 
    937         req_args &= 0x000F;
    938         if ( num_args < req_args )
    939           goto Stack_Underflow;
    940         args     -= req_args;
    941         num_args -= req_args;
    942 
    943         /* At this point, `args' points to the first argument of the  */
    944         /* operand in case `req_args' isn't zero.  Otherwise, we have */
    945         /* to adjust `args' manually.                                 */
    946 
    947         /* Note that we only pop arguments from the stack which we    */
    948         /* really need and can digest so that we can continue in case */
    949         /* of superfluous stack elements.                             */
    950 
    951         switch ( op )
    952         {
    953         case cff_op_hstem:
    954         case cff_op_vstem:
    955         case cff_op_hstemhm:
    956         case cff_op_vstemhm:
    957           /* the number of arguments is always even here */
    958           FT_TRACE4((
    959               op == cff_op_hstem   ? " hstem\n"   :
    960             ( op == cff_op_vstem   ? " vstem\n"   :
    961             ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
    962 
    963           if ( hinter )
    964             hinter->stems( hinter->hints,
    965                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
    966                            num_args / 2,
    967                            args - ( num_args & ~1 ) );
    968 
    969           decoder->num_hints += num_args / 2;
    970           args = stack;
    971           break;
    972 
    973         case cff_op_hintmask:
    974         case cff_op_cntrmask:
    975           FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
    976 
    977           /* implement vstem when needed --                        */
    978           /* the specification doesn't say it, but this also works */
    979           /* with the 'cntrmask' operator                          */
    980           /*                                                       */
    981           if ( num_args > 0 )
    982           {
    983             if ( hinter )
    984               hinter->stems( hinter->hints,
    985                              0,
    986                              num_args / 2,
    987                              args - ( num_args & ~1 ) );
    988 
    989             decoder->num_hints += num_args / 2;
    990           }
    991 
    992           /* In a valid charstring there must be at least one byte */
    993           /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
    994           /* instruction).  Additionally, there must be space for  */
    995           /* `num_hints' bits.                                     */
    996 
    997           if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
    998             goto Syntax_Error;
    999 
   1000           if ( hinter )
   1001           {
   1002             if ( op == cff_op_hintmask )
   1003               hinter->hintmask( hinter->hints,
   1004                                 (FT_UInt)builder->current->n_points,
   1005                                 (FT_UInt)decoder->num_hints,
   1006                                 ip );
   1007             else
   1008               hinter->counter( hinter->hints,
   1009                                (FT_UInt)decoder->num_hints,
   1010                                ip );
   1011           }
   1012 
   1013 #ifdef FT_DEBUG_LEVEL_TRACE
   1014           {
   1015             FT_UInt  maskbyte;
   1016 
   1017 
   1018             FT_TRACE4(( " (maskbytes:" ));
   1019 
   1020             for ( maskbyte = 0;
   1021                   maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
   1022                   maskbyte++, ip++ )
   1023               FT_TRACE4(( " 0x%02X", *ip ));
   1024 
   1025             FT_TRACE4(( ")\n" ));
   1026           }
   1027 #else
   1028           ip += ( decoder->num_hints + 7 ) >> 3;
   1029 #endif
   1030           args = stack;
   1031           break;
   1032 
   1033         case cff_op_rmoveto:
   1034           FT_TRACE4(( " rmoveto\n" ));
   1035 
   1036           cff_builder_close_contour( builder );
   1037           builder->path_begun = 0;
   1038           x    = ADD_LONG( x, args[-2] );
   1039           y    = ADD_LONG( y, args[-1] );
   1040           args = stack;
   1041           break;
   1042 
   1043         case cff_op_vmoveto:
   1044           FT_TRACE4(( " vmoveto\n" ));
   1045 
   1046           cff_builder_close_contour( builder );
   1047           builder->path_begun = 0;
   1048           y    = ADD_LONG( y, args[-1] );
   1049           args = stack;
   1050           break;
   1051 
   1052         case cff_op_hmoveto:
   1053           FT_TRACE4(( " hmoveto\n" ));
   1054 
   1055           cff_builder_close_contour( builder );
   1056           builder->path_begun = 0;
   1057           x    = ADD_LONG( x, args[-1] );
   1058           args = stack;
   1059           break;
   1060 
   1061         case cff_op_rlineto:
   1062           FT_TRACE4(( " rlineto\n" ));
   1063 
   1064           if ( cff_builder_start_point( builder, x, y )  ||
   1065                cff_check_points( builder, num_args / 2 ) )
   1066             goto Fail;
   1067 
   1068           if ( num_args < 2 )
   1069             goto Stack_Underflow;
   1070 
   1071           args -= num_args & ~1;
   1072           while ( args < decoder->top )
   1073           {
   1074             x = ADD_LONG( x, args[0] );
   1075             y = ADD_LONG( y, args[1] );
   1076             cff_builder_add_point( builder, x, y, 1 );
   1077             args += 2;
   1078           }
   1079           args = stack;
   1080           break;
   1081 
   1082         case cff_op_hlineto:
   1083         case cff_op_vlineto:
   1084           {
   1085             FT_Int  phase = ( op == cff_op_hlineto );
   1086 
   1087 
   1088             FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
   1089                                              : " vlineto\n" ));
   1090 
   1091             if ( num_args < 0 )
   1092               goto Stack_Underflow;
   1093 
   1094             /* there exist subsetted fonts (found in PDFs) */
   1095             /* which call `hlineto' without arguments      */
   1096             if ( num_args == 0 )
   1097               break;
   1098 
   1099             if ( cff_builder_start_point( builder, x, y ) ||
   1100                  cff_check_points( builder, num_args )    )
   1101               goto Fail;
   1102 
   1103             args = stack;
   1104             while ( args < decoder->top )
   1105             {
   1106               if ( phase )
   1107                 x = ADD_LONG( x, args[0] );
   1108               else
   1109                 y = ADD_LONG( y, args[0] );
   1110 
   1111               if ( cff_builder_add_point1( builder, x, y ) )
   1112                 goto Fail;
   1113 
   1114               args++;
   1115               phase ^= 1;
   1116             }
   1117             args = stack;
   1118           }
   1119           break;
   1120 
   1121         case cff_op_rrcurveto:
   1122           {
   1123             FT_Int  nargs;
   1124 
   1125 
   1126             FT_TRACE4(( " rrcurveto\n" ));
   1127 
   1128             if ( num_args < 6 )
   1129               goto Stack_Underflow;
   1130 
   1131             nargs = num_args - num_args % 6;
   1132 
   1133             if ( cff_builder_start_point( builder, x, y ) ||
   1134                  cff_check_points( builder, nargs / 2 )   )
   1135               goto Fail;
   1136 
   1137             args -= nargs;
   1138             while ( args < decoder->top )
   1139             {
   1140               x = ADD_LONG( x, args[0] );
   1141               y = ADD_LONG( y, args[1] );
   1142               cff_builder_add_point( builder, x, y, 0 );
   1143 
   1144               x = ADD_LONG( x, args[2] );
   1145               y = ADD_LONG( y, args[3] );
   1146               cff_builder_add_point( builder, x, y, 0 );
   1147 
   1148               x = ADD_LONG( x, args[4] );
   1149               y = ADD_LONG( y, args[5] );
   1150               cff_builder_add_point( builder, x, y, 1 );
   1151 
   1152               args += 6;
   1153             }
   1154             args = stack;
   1155           }
   1156           break;
   1157 
   1158         case cff_op_vvcurveto:
   1159           {
   1160             FT_Int  nargs;
   1161 
   1162 
   1163             FT_TRACE4(( " vvcurveto\n" ));
   1164 
   1165             if ( num_args < 4 )
   1166               goto Stack_Underflow;
   1167 
   1168             /* if num_args isn't of the form 4n or 4n+1, */
   1169             /* we enforce it by clearing the second bit  */
   1170 
   1171             nargs = num_args & ~2;
   1172 
   1173             if ( cff_builder_start_point( builder, x, y ) )
   1174               goto Fail;
   1175 
   1176             args -= nargs;
   1177 
   1178             if ( nargs & 1 )
   1179             {
   1180               x = ADD_LONG( x, args[0] );
   1181               args++;
   1182               nargs--;
   1183             }
   1184 
   1185             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
   1186               goto Fail;
   1187 
   1188             while ( args < decoder->top )
   1189             {
   1190               y = ADD_LONG( y, args[0] );
   1191               cff_builder_add_point( builder, x, y, 0 );
   1192 
   1193               x = ADD_LONG( x, args[1] );
   1194               y = ADD_LONG( y, args[2] );
   1195               cff_builder_add_point( builder, x, y, 0 );
   1196 
   1197               y = ADD_LONG( y, args[3] );
   1198               cff_builder_add_point( builder, x, y, 1 );
   1199 
   1200               args += 4;
   1201             }
   1202             args = stack;
   1203           }
   1204           break;
   1205 
   1206         case cff_op_hhcurveto:
   1207           {
   1208             FT_Int  nargs;
   1209 
   1210 
   1211             FT_TRACE4(( " hhcurveto\n" ));
   1212 
   1213             if ( num_args < 4 )
   1214               goto Stack_Underflow;
   1215 
   1216             /* if num_args isn't of the form 4n or 4n+1, */
   1217             /* we enforce it by clearing the second bit  */
   1218 
   1219             nargs = num_args & ~2;
   1220 
   1221             if ( cff_builder_start_point( builder, x, y ) )
   1222               goto Fail;
   1223 
   1224             args -= nargs;
   1225             if ( nargs & 1 )
   1226             {
   1227               y = ADD_LONG( y, args[0] );
   1228               args++;
   1229               nargs--;
   1230             }
   1231 
   1232             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
   1233               goto Fail;
   1234 
   1235             while ( args < decoder->top )
   1236             {
   1237               x = ADD_LONG( x, args[0] );
   1238               cff_builder_add_point( builder, x, y, 0 );
   1239 
   1240               x = ADD_LONG( x, args[1] );
   1241               y = ADD_LONG( y, args[2] );
   1242               cff_builder_add_point( builder, x, y, 0 );
   1243 
   1244               x = ADD_LONG( x, args[3] );
   1245               cff_builder_add_point( builder, x, y, 1 );
   1246 
   1247               args += 4;
   1248             }
   1249             args = stack;
   1250           }
   1251           break;
   1252 
   1253         case cff_op_vhcurveto:
   1254         case cff_op_hvcurveto:
   1255           {
   1256             FT_Int  phase;
   1257             FT_Int  nargs;
   1258 
   1259 
   1260             FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
   1261                                                : " hvcurveto\n" ));
   1262 
   1263             if ( cff_builder_start_point( builder, x, y ) )
   1264               goto Fail;
   1265 
   1266             if ( num_args < 4 )
   1267               goto Stack_Underflow;
   1268 
   1269             /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
   1270             /* we enforce it by clearing the second bit               */
   1271 
   1272             nargs = num_args & ~2;
   1273 
   1274             args -= nargs;
   1275             if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
   1276               goto Stack_Underflow;
   1277 
   1278             phase = ( op == cff_op_hvcurveto );
   1279 
   1280             while ( nargs >= 4 )
   1281             {
   1282               nargs -= 4;
   1283               if ( phase )
   1284               {
   1285                 x = ADD_LONG( x, args[0] );
   1286                 cff_builder_add_point( builder, x, y, 0 );
   1287 
   1288                 x = ADD_LONG( x, args[1] );
   1289                 y = ADD_LONG( y, args[2] );
   1290                 cff_builder_add_point( builder, x, y, 0 );
   1291 
   1292                 y = ADD_LONG( y, args[3] );
   1293                 if ( nargs == 1 )
   1294                   x = ADD_LONG( x, args[4] );
   1295                 cff_builder_add_point( builder, x, y, 1 );
   1296               }
   1297               else
   1298               {
   1299                 y = ADD_LONG( y, args[0] );
   1300                 cff_builder_add_point( builder, x, y, 0 );
   1301 
   1302                 x = ADD_LONG( x, args[1] );
   1303                 y = ADD_LONG( y, args[2] );
   1304                 cff_builder_add_point( builder, x, y, 0 );
   1305 
   1306                 x = ADD_LONG( x, args[3] );
   1307                 if ( nargs == 1 )
   1308                   y = ADD_LONG( y, args[4] );
   1309                 cff_builder_add_point( builder, x, y, 1 );
   1310               }
   1311               args  += 4;
   1312               phase ^= 1;
   1313             }
   1314             args = stack;
   1315           }
   1316           break;
   1317 
   1318         case cff_op_rlinecurve:
   1319           {
   1320             FT_Int  num_lines;
   1321             FT_Int  nargs;
   1322 
   1323 
   1324             FT_TRACE4(( " rlinecurve\n" ));
   1325 
   1326             if ( num_args < 8 )
   1327               goto Stack_Underflow;
   1328 
   1329             nargs     = num_args & ~1;
   1330             num_lines = ( nargs - 6 ) / 2;
   1331 
   1332             if ( cff_builder_start_point( builder, x, y )   ||
   1333                  cff_check_points( builder, num_lines + 3 ) )
   1334               goto Fail;
   1335 
   1336             args -= nargs;
   1337 
   1338             /* first, add the line segments */
   1339             while ( num_lines > 0 )
   1340             {
   1341               x = ADD_LONG( x, args[0] );
   1342               y = ADD_LONG( y, args[1] );
   1343               cff_builder_add_point( builder, x, y, 1 );
   1344 
   1345               args += 2;
   1346               num_lines--;
   1347             }
   1348 
   1349             /* then the curve */
   1350             x = ADD_LONG( x, args[0] );
   1351             y = ADD_LONG( y, args[1] );
   1352             cff_builder_add_point( builder, x, y, 0 );
   1353 
   1354             x = ADD_LONG( x, args[2] );
   1355             y = ADD_LONG( y, args[3] );
   1356             cff_builder_add_point( builder, x, y, 0 );
   1357 
   1358             x = ADD_LONG( x, args[4] );
   1359             y = ADD_LONG( y, args[5] );
   1360             cff_builder_add_point( builder, x, y, 1 );
   1361 
   1362             args = stack;
   1363           }
   1364           break;
   1365 
   1366         case cff_op_rcurveline:
   1367           {
   1368             FT_Int  num_curves;
   1369             FT_Int  nargs;
   1370 
   1371 
   1372             FT_TRACE4(( " rcurveline\n" ));
   1373 
   1374             if ( num_args < 8 )
   1375               goto Stack_Underflow;
   1376 
   1377             nargs      = num_args - 2;
   1378             nargs      = nargs - nargs % 6 + 2;
   1379             num_curves = ( nargs - 2 ) / 6;
   1380 
   1381             if ( cff_builder_start_point( builder, x, y )        ||
   1382                  cff_check_points( builder, num_curves * 3 + 2 ) )
   1383               goto Fail;
   1384 
   1385             args -= nargs;
   1386 
   1387             /* first, add the curves */
   1388             while ( num_curves > 0 )
   1389             {
   1390               x = ADD_LONG( x, args[0] );
   1391               y = ADD_LONG( y, args[1] );
   1392               cff_builder_add_point( builder, x, y, 0 );
   1393 
   1394               x = ADD_LONG( x, args[2] );
   1395               y = ADD_LONG( y, args[3] );
   1396               cff_builder_add_point( builder, x, y, 0 );
   1397 
   1398               x = ADD_LONG( x, args[4] );
   1399               y = ADD_LONG( y, args[5] );
   1400               cff_builder_add_point( builder, x, y, 1 );
   1401 
   1402               args += 6;
   1403               num_curves--;
   1404             }
   1405 
   1406             /* then the final line */
   1407             x = ADD_LONG( x, args[0] );
   1408             y = ADD_LONG( y, args[1] );
   1409             cff_builder_add_point( builder, x, y, 1 );
   1410 
   1411             args = stack;
   1412           }
   1413           break;
   1414 
   1415         case cff_op_hflex1:
   1416           {
   1417             FT_Pos  start_y;
   1418 
   1419 
   1420             FT_TRACE4(( " hflex1\n" ));
   1421 
   1422             /* adding five more points: 4 control points, 1 on-curve point */
   1423             /* -- make sure we have enough space for the start point if it */
   1424             /* needs to be added                                           */
   1425             if ( cff_builder_start_point( builder, x, y ) ||
   1426                  cff_check_points( builder, 6 )           )
   1427               goto Fail;
   1428 
   1429             /* record the starting point's y position for later use */
   1430             start_y = y;
   1431 
   1432             /* first control point */
   1433             x = ADD_LONG( x, args[0] );
   1434             y = ADD_LONG( y, args[1] );
   1435             cff_builder_add_point( builder, x, y, 0 );
   1436 
   1437             /* second control point */
   1438             x = ADD_LONG( x, args[2] );
   1439             y = ADD_LONG( y, args[3] );
   1440             cff_builder_add_point( builder, x, y, 0 );
   1441 
   1442             /* join point; on curve, with y-value the same as the last */
   1443             /* control point's y-value                                 */
   1444             x = ADD_LONG( x, args[4] );
   1445             cff_builder_add_point( builder, x, y, 1 );
   1446 
   1447             /* third control point, with y-value the same as the join */
   1448             /* point's y-value                                        */
   1449             x = ADD_LONG( x, args[5] );
   1450             cff_builder_add_point( builder, x, y, 0 );
   1451 
   1452             /* fourth control point */
   1453             x = ADD_LONG( x, args[6] );
   1454             y = ADD_LONG( y, args[7] );
   1455             cff_builder_add_point( builder, x, y, 0 );
   1456 
   1457             /* ending point, with y-value the same as the start   */
   1458             x = ADD_LONG( x, args[8] );
   1459             y = start_y;
   1460             cff_builder_add_point( builder, x, y, 1 );
   1461 
   1462             args = stack;
   1463             break;
   1464           }
   1465 
   1466         case cff_op_hflex:
   1467           {
   1468             FT_Pos  start_y;
   1469 
   1470 
   1471             FT_TRACE4(( " hflex\n" ));
   1472 
   1473             /* adding six more points; 4 control points, 2 on-curve points */
   1474             if ( cff_builder_start_point( builder, x, y ) ||
   1475                  cff_check_points( builder, 6 )           )
   1476               goto Fail;
   1477 
   1478             /* record the starting point's y-position for later use */
   1479             start_y = y;
   1480 
   1481             /* first control point */
   1482             x = ADD_LONG( x, args[0] );
   1483             cff_builder_add_point( builder, x, y, 0 );
   1484 
   1485             /* second control point */
   1486             x = ADD_LONG( x, args[1] );
   1487             y = ADD_LONG( y, args[2] );
   1488             cff_builder_add_point( builder, x, y, 0 );
   1489 
   1490             /* join point; on curve, with y-value the same as the last */
   1491             /* control point's y-value                                 */
   1492             x = ADD_LONG( x, args[3] );
   1493             cff_builder_add_point( builder, x, y, 1 );
   1494 
   1495             /* third control point, with y-value the same as the join */
   1496             /* point's y-value                                        */
   1497             x = ADD_LONG( x, args[4] );
   1498             cff_builder_add_point( builder, x, y, 0 );
   1499 
   1500             /* fourth control point */
   1501             x = ADD_LONG( x, args[5] );
   1502             y = start_y;
   1503             cff_builder_add_point( builder, x, y, 0 );
   1504 
   1505             /* ending point, with y-value the same as the start point's */
   1506             /* y-value -- we don't add this point, though               */
   1507             x = ADD_LONG( x, args[6] );
   1508             cff_builder_add_point( builder, x, y, 1 );
   1509 
   1510             args = stack;
   1511             break;
   1512           }
   1513 
   1514         case cff_op_flex1:
   1515           {
   1516             FT_Pos     start_x, start_y; /* record start x, y values for */
   1517                                          /* alter use                    */
   1518             FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
   1519                                          /* algorithm below              */
   1520             FT_Int     horizontal, count;
   1521             FT_Fixed*  temp;
   1522 
   1523 
   1524             FT_TRACE4(( " flex1\n" ));
   1525 
   1526             /* adding six more points; 4 control points, 2 on-curve points */
   1527             if ( cff_builder_start_point( builder, x, y ) ||
   1528                  cff_check_points( builder, 6 )           )
   1529               goto Fail;
   1530 
   1531             /* record the starting point's x, y position for later use */
   1532             start_x = x;
   1533             start_y = y;
   1534 
   1535             /* XXX: figure out whether this is supposed to be a horizontal */
   1536             /*      or vertical flex; the Type 2 specification is vague... */
   1537 
   1538             temp = args;
   1539 
   1540             /* grab up to the last argument */
   1541             for ( count = 5; count > 0; count-- )
   1542             {
   1543               dx    = ADD_LONG( dx, temp[0] );
   1544               dy    = ADD_LONG( dy, temp[1] );
   1545               temp += 2;
   1546             }
   1547 
   1548             if ( dx < 0 )
   1549               dx = -dx;
   1550             if ( dy < 0 )
   1551               dy = -dy;
   1552 
   1553             /* strange test, but here it is... */
   1554             horizontal = ( dx > dy );
   1555 
   1556             for ( count = 5; count > 0; count-- )
   1557             {
   1558               x = ADD_LONG( x, args[0] );
   1559               y = ADD_LONG( y, args[1] );
   1560               cff_builder_add_point( builder, x, y,
   1561                                      (FT_Bool)( count == 3 ) );
   1562               args += 2;
   1563             }
   1564 
   1565             /* is last operand an x- or y-delta? */
   1566             if ( horizontal )
   1567             {
   1568               x = ADD_LONG( x, args[0] );
   1569               y = start_y;
   1570             }
   1571             else
   1572             {
   1573               x = start_x;
   1574               y = ADD_LONG( y, args[0] );
   1575             }
   1576 
   1577             cff_builder_add_point( builder, x, y, 1 );
   1578 
   1579             args = stack;
   1580             break;
   1581            }
   1582 
   1583         case cff_op_flex:
   1584           {
   1585             FT_UInt  count;
   1586 
   1587 
   1588             FT_TRACE4(( " flex\n" ));
   1589 
   1590             if ( cff_builder_start_point( builder, x, y ) ||
   1591                  cff_check_points( builder, 6 )           )
   1592               goto Fail;
   1593 
   1594             for ( count = 6; count > 0; count-- )
   1595             {
   1596               x = ADD_LONG( x, args[0] );
   1597               y = ADD_LONG( y, args[1] );
   1598               cff_builder_add_point( builder, x, y,
   1599                                      (FT_Bool)( count == 4 || count == 1 ) );
   1600               args += 2;
   1601             }
   1602 
   1603             args = stack;
   1604           }
   1605           break;
   1606 
   1607         case cff_op_seac:
   1608           FT_TRACE4(( " seac\n" ));
   1609 
   1610           error = cff_operator_seac( decoder,
   1611                                      args[0], args[1], args[2],
   1612                                      (FT_Int)( args[3] >> 16 ),
   1613                                      (FT_Int)( args[4] >> 16 ) );
   1614 
   1615           /* add current outline to the glyph slot */
   1616           FT_GlyphLoader_Add( builder->loader );
   1617 
   1618           /* return now! */
   1619           FT_TRACE4(( "\n" ));
   1620           return error;
   1621 
   1622         case cff_op_endchar:
   1623           /* in dictionaries, `endchar' simply indicates end of data */
   1624           if ( in_dict )
   1625             return error;
   1626 
   1627           FT_TRACE4(( " endchar\n" ));
   1628 
   1629           /* We are going to emulate the seac operator. */
   1630           if ( num_args >= 4 )
   1631           {
   1632             /* Save glyph width so that the subglyphs don't overwrite it. */
   1633             FT_Pos  glyph_width = decoder->glyph_width;
   1634 
   1635 
   1636             error = cff_operator_seac( decoder,
   1637                                        0L, args[-4], args[-3],
   1638                                        (FT_Int)( args[-2] >> 16 ),
   1639                                        (FT_Int)( args[-1] >> 16 ) );
   1640 
   1641             decoder->glyph_width = glyph_width;
   1642           }
   1643           else
   1644           {
   1645             cff_builder_close_contour( builder );
   1646 
   1647             /* close hints recording session */
   1648             if ( hinter )
   1649             {
   1650               if ( hinter->close( hinter->hints,
   1651                                   (FT_UInt)builder->current->n_points ) )
   1652                 goto Syntax_Error;
   1653 
   1654               /* apply hints to the loaded glyph outline now */
   1655               error = hinter->apply( hinter->hints,
   1656                                      builder->current,
   1657                                      (PSH_Globals)builder->hints_globals,
   1658                                      decoder->hint_mode );
   1659               if ( error )
   1660                 goto Fail;
   1661             }
   1662 
   1663             /* add current outline to the glyph slot */
   1664             FT_GlyphLoader_Add( builder->loader );
   1665           }
   1666 
   1667           /* return now! */
   1668           FT_TRACE4(( "\n" ));
   1669           return error;
   1670 
   1671         case cff_op_abs:
   1672           FT_TRACE4(( " abs\n" ));
   1673 
   1674           if ( args[0] < 0 )
   1675           {
   1676             if ( args[0] == FT_LONG_MIN )
   1677               args[0] = FT_LONG_MAX;
   1678             else
   1679               args[0] = -args[0];
   1680           }
   1681           args++;
   1682           break;
   1683 
   1684         case cff_op_add:
   1685           FT_TRACE4(( " add\n" ));
   1686 
   1687           args[0] = ADD_LONG( args[0], args[1] );
   1688           args++;
   1689           break;
   1690 
   1691         case cff_op_sub:
   1692           FT_TRACE4(( " sub\n" ));
   1693 
   1694           args[0] = SUB_LONG( args[0], args[1] );
   1695           args++;
   1696           break;
   1697 
   1698         case cff_op_div:
   1699           FT_TRACE4(( " div\n" ));
   1700 
   1701           args[0] = FT_DivFix( args[0], args[1] );
   1702           args++;
   1703           break;
   1704 
   1705         case cff_op_neg:
   1706           FT_TRACE4(( " neg\n" ));
   1707 
   1708           if ( args[0] == FT_LONG_MIN )
   1709             args[0] = FT_LONG_MAX;
   1710           args[0] = -args[0];
   1711           args++;
   1712           break;
   1713 
   1714         case cff_op_random:
   1715           FT_TRACE4(( " random\n" ));
   1716 
   1717           /* only use the lower 16 bits of `random'  */
   1718           /* to generate a number in the range (0;1] */
   1719           args[0] = (FT_Fixed)
   1720                       ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
   1721           args++;
   1722 
   1723           decoder->current_subfont->random =
   1724             cff_random( decoder->current_subfont->random );
   1725           break;
   1726 
   1727         case cff_op_mul:
   1728           FT_TRACE4(( " mul\n" ));
   1729 
   1730           args[0] = FT_MulFix( args[0], args[1] );
   1731           args++;
   1732           break;
   1733 
   1734         case cff_op_sqrt:
   1735           FT_TRACE4(( " sqrt\n" ));
   1736 
   1737           if ( args[0] > 0 )
   1738           {
   1739             FT_Fixed  root = args[0];
   1740             FT_Fixed  new_root;
   1741 
   1742 
   1743             for (;;)
   1744             {
   1745               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
   1746               if ( new_root == root )
   1747                 break;
   1748               root = new_root;
   1749             }
   1750             args[0] = new_root;
   1751           }
   1752           else
   1753             args[0] = 0;
   1754           args++;
   1755           break;
   1756 
   1757         case cff_op_drop:
   1758           /* nothing */
   1759           FT_TRACE4(( " drop\n" ));
   1760 
   1761           break;
   1762 
   1763         case cff_op_exch:
   1764           {
   1765             FT_Fixed  tmp;
   1766 
   1767 
   1768             FT_TRACE4(( " exch\n" ));
   1769 
   1770             tmp     = args[0];
   1771             args[0] = args[1];
   1772             args[1] = tmp;
   1773             args   += 2;
   1774           }
   1775           break;
   1776 
   1777         case cff_op_index:
   1778           {
   1779             FT_Int  idx = (FT_Int)( args[0] >> 16 );
   1780 
   1781 
   1782             FT_TRACE4(( " index\n" ));
   1783 
   1784             if ( idx < 0 )
   1785               idx = 0;
   1786             else if ( idx > num_args - 2 )
   1787               idx = num_args - 2;
   1788             args[0] = args[-( idx + 1 )];
   1789             args++;
   1790           }
   1791           break;
   1792 
   1793         case cff_op_roll:
   1794           {
   1795             FT_Int  count = (FT_Int)( args[0] >> 16 );
   1796             FT_Int  idx   = (FT_Int)( args[1] >> 16 );
   1797 
   1798 
   1799             FT_TRACE4(( " roll\n" ));
   1800 
   1801             if ( count <= 0 )
   1802               count = 1;
   1803 
   1804             args -= count;
   1805             if ( args < stack )
   1806               goto Stack_Underflow;
   1807 
   1808             if ( idx >= 0 )
   1809             {
   1810               while ( idx > 0 )
   1811               {
   1812                 FT_Fixed  tmp = args[count - 1];
   1813                 FT_Int    i;
   1814 
   1815 
   1816                 for ( i = count - 2; i >= 0; i-- )
   1817                   args[i + 1] = args[i];
   1818                 args[0] = tmp;
   1819                 idx--;
   1820               }
   1821             }
   1822             else
   1823             {
   1824               while ( idx < 0 )
   1825               {
   1826                 FT_Fixed  tmp = args[0];
   1827                 FT_Int    i;
   1828 
   1829 
   1830                 for ( i = 0; i < count - 1; i++ )
   1831                   args[i] = args[i + 1];
   1832                 args[count - 1] = tmp;
   1833                 idx++;
   1834               }
   1835             }
   1836             args += count;
   1837           }
   1838           break;
   1839 
   1840         case cff_op_dup:
   1841           FT_TRACE4(( " dup\n" ));
   1842 
   1843           args[1] = args[0];
   1844           args   += 2;
   1845           break;
   1846 
   1847         case cff_op_put:
   1848           {
   1849             FT_Fixed  val = args[0];
   1850             FT_Int    idx = (FT_Int)( args[1] >> 16 );
   1851 
   1852 
   1853             FT_TRACE4(( " put\n" ));
   1854 
   1855             /* the Type2 specification before version 16-March-2000 */
   1856             /* didn't give a hard-coded size limit of the temporary */
   1857             /* storage array; instead, an argument of the           */
   1858             /* `MultipleMaster' operator set the size               */
   1859             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
   1860               decoder->buildchar[idx] = val;
   1861           }
   1862           break;
   1863 
   1864         case cff_op_get:
   1865           {
   1866             FT_Int    idx = (FT_Int)( args[0] >> 16 );
   1867             FT_Fixed  val = 0;
   1868 
   1869 
   1870             FT_TRACE4(( " get\n" ));
   1871 
   1872             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
   1873               val = decoder->buildchar[idx];
   1874 
   1875             args[0] = val;
   1876             args++;
   1877           }
   1878           break;
   1879 
   1880         case cff_op_store:
   1881           /* this operator was removed from the Type2 specification */
   1882           /* in version 16-March-2000                               */
   1883 
   1884           /* since we currently don't handle interpolation of multiple */
   1885           /* master fonts, this is a no-op                             */
   1886           FT_TRACE4(( " store\n" ));
   1887           break;
   1888 
   1889         case cff_op_load:
   1890           /* this operator was removed from the Type2 specification */
   1891           /* in version 16-March-2000                               */
   1892           {
   1893             FT_Int  reg_idx = (FT_Int)args[0];
   1894             FT_Int  idx     = (FT_Int)args[1];
   1895             FT_Int  count   = (FT_Int)args[2];
   1896 
   1897 
   1898             FT_TRACE4(( " load\n" ));
   1899 
   1900             /* since we currently don't handle interpolation of multiple */
   1901             /* master fonts, we store a vector [1 0 0 ...] in the        */
   1902             /* temporary storage array regardless of the Registry index  */
   1903             if ( reg_idx >= 0 && reg_idx <= 2             &&
   1904                  idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
   1905                  count >= 0 && count <= num_axes          )
   1906             {
   1907               FT_Int  end, i;
   1908 
   1909 
   1910               end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
   1911 
   1912               if ( idx < end )
   1913                 decoder->buildchar[idx] = 1 << 16;
   1914 
   1915               for ( i = idx + 1; i < end; i++ )
   1916                 decoder->buildchar[i] = 0;
   1917             }
   1918           }
   1919           break;
   1920 
   1921         case cff_op_blend:
   1922           /* this operator was removed from the Type2 specification */
   1923           /* in version 16-March-2000                               */
   1924           {
   1925             FT_Int  num_results = (FT_Int)( args[0] >> 16 );
   1926 
   1927 
   1928             FT_TRACE4(( " blend\n" ));
   1929 
   1930             if ( num_results < 0 )
   1931               goto Syntax_Error;
   1932 
   1933             if ( num_results * (FT_Int)num_designs > num_args )
   1934               goto Stack_Underflow;
   1935 
   1936             /* since we currently don't handle interpolation of multiple */
   1937             /* master fonts, return the `num_results' values of the      */
   1938             /* first master                                              */
   1939             args     -= num_results * ( num_designs - 1 );
   1940             num_args -= num_results * ( num_designs - 1 );
   1941           }
   1942           break;
   1943 
   1944         case cff_op_dotsection:
   1945           /* this operator is deprecated and ignored by the parser */
   1946           FT_TRACE4(( " dotsection\n" ));
   1947           break;
   1948 
   1949         case cff_op_closepath:
   1950           /* this is an invalid Type 2 operator; however, there        */
   1951           /* exist fonts which are incorrectly converted from probably */
   1952           /* Type 1 to CFF, and some parsers seem to accept it         */
   1953 
   1954           FT_TRACE4(( " closepath (invalid op)\n" ));
   1955 
   1956           args = stack;
   1957           break;
   1958 
   1959         case cff_op_hsbw:
   1960           /* this is an invalid Type 2 operator; however, there        */
   1961           /* exist fonts which are incorrectly converted from probably */
   1962           /* Type 1 to CFF, and some parsers seem to accept it         */
   1963 
   1964           FT_TRACE4(( " hsbw (invalid op)\n" ));
   1965 
   1966           decoder->glyph_width =
   1967             ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
   1968 
   1969           decoder->builder.left_bearing.x = args[0];
   1970           decoder->builder.left_bearing.y = 0;
   1971 
   1972           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   1973           y    = decoder->builder.pos_y;
   1974           args = stack;
   1975           break;
   1976 
   1977         case cff_op_sbw:
   1978           /* this is an invalid Type 2 operator; however, there        */
   1979           /* exist fonts which are incorrectly converted from probably */
   1980           /* Type 1 to CFF, and some parsers seem to accept it         */
   1981 
   1982           FT_TRACE4(( " sbw (invalid op)\n" ));
   1983 
   1984           decoder->glyph_width =
   1985             ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
   1986 
   1987           decoder->builder.left_bearing.x = args[0];
   1988           decoder->builder.left_bearing.y = args[1];
   1989 
   1990           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   1991           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
   1992           args = stack;
   1993           break;
   1994 
   1995         case cff_op_setcurrentpoint:
   1996           /* this is an invalid Type 2 operator; however, there        */
   1997           /* exist fonts which are incorrectly converted from probably */
   1998           /* Type 1 to CFF, and some parsers seem to accept it         */
   1999 
   2000           FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
   2001 
   2002           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
   2003           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
   2004           args = stack;
   2005           break;
   2006 
   2007         case cff_op_callothersubr:
   2008           /* this is an invalid Type 2 operator; however, there        */
   2009           /* exist fonts which are incorrectly converted from probably */
   2010           /* Type 1 to CFF, and some parsers seem to accept it         */
   2011 
   2012           FT_TRACE4(( " callothersubr (invalid op)\n" ));
   2013 
   2014           /* subsequent `pop' operands should add the arguments,       */
   2015           /* this is the implementation described for `unknown' other  */
   2016           /* subroutines in the Type1 spec.                            */
   2017           /*                                                           */
   2018           /* XXX Fix return arguments (see discussion below).          */
   2019           args -= 2 + ( args[-2] >> 16 );
   2020           if ( args < stack )
   2021             goto Stack_Underflow;
   2022           break;
   2023 
   2024         case cff_op_pop:
   2025           /* this is an invalid Type 2 operator; however, there        */
   2026           /* exist fonts which are incorrectly converted from probably */
   2027           /* Type 1 to CFF, and some parsers seem to accept it         */
   2028 
   2029           FT_TRACE4(( " pop (invalid op)\n" ));
   2030 
   2031           /* XXX Increasing `args' is wrong: After a certain number of */
   2032           /* `pop's we get a stack overflow.  Reason for doing it is   */
   2033           /* code like this (actually found in a CFF font):            */
   2034           /*                                                           */
   2035           /*   17 1 3 callothersubr                                    */
   2036           /*   pop                                                     */
   2037           /*   callsubr                                                */
   2038           /*                                                           */
   2039           /* Since we handle `callothersubr' as a no-op, and           */
   2040           /* `callsubr' needs at least one argument, `pop' can't be a  */
   2041           /* no-op too as it basically should be.                      */
   2042           /*                                                           */
   2043           /* The right solution would be to provide real support for   */
   2044           /* `callothersubr' as done in `t1decode.c', however, given   */
   2045           /* the fact that CFF fonts with `pop' are invalid, it is     */
   2046           /* questionable whether it is worth the time.                */
   2047           args++;
   2048           break;
   2049 
   2050         case cff_op_and:
   2051           {
   2052             FT_Fixed  cond = ( args[0] && args[1] );
   2053 
   2054 
   2055             FT_TRACE4(( " and\n" ));
   2056 
   2057             args[0] = cond ? 0x10000L : 0;
   2058             args++;
   2059           }
   2060           break;
   2061 
   2062         case cff_op_or:
   2063           {
   2064             FT_Fixed  cond = ( args[0] || args[1] );
   2065 
   2066 
   2067             FT_TRACE4(( " or\n" ));
   2068 
   2069             args[0] = cond ? 0x10000L : 0;
   2070             args++;
   2071           }
   2072           break;
   2073 
   2074         case cff_op_not:
   2075           {
   2076             FT_Fixed  cond = !args[0];
   2077 
   2078 
   2079             FT_TRACE4(( " not\n" ));
   2080 
   2081             args[0] = cond ? 0x10000L : 0;
   2082             args++;
   2083           }
   2084           break;
   2085 
   2086         case cff_op_eq:
   2087           {
   2088             FT_Fixed  cond = ( args[0] == args[1] );
   2089 
   2090 
   2091             FT_TRACE4(( " eq\n" ));
   2092 
   2093             args[0] = cond ? 0x10000L : 0;
   2094             args++;
   2095           }
   2096           break;
   2097 
   2098         case cff_op_ifelse:
   2099           {
   2100             FT_Fixed  cond = ( args[2] <= args[3] );
   2101 
   2102 
   2103             FT_TRACE4(( " ifelse\n" ));
   2104 
   2105             if ( !cond )
   2106               args[0] = args[1];
   2107             args++;
   2108           }
   2109           break;
   2110 
   2111         case cff_op_callsubr:
   2112           {
   2113             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
   2114                                       decoder->locals_bias );
   2115 
   2116 
   2117             FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
   2118                         idx,
   2119                         zone - decoder->zones + 1 ));
   2120 
   2121             if ( idx >= decoder->num_locals )
   2122             {
   2123               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2124                          " invalid local subr index\n" ));
   2125               goto Syntax_Error;
   2126             }
   2127 
   2128             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
   2129             {
   2130               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2131                          " too many nested subrs\n" ));
   2132               goto Syntax_Error;
   2133             }
   2134 
   2135             zone->cursor = ip;  /* save current instruction pointer */
   2136 
   2137             zone++;
   2138             zone->base   = decoder->locals[idx];
   2139             zone->limit  = decoder->locals[idx + 1];
   2140             zone->cursor = zone->base;
   2141 
   2142             if ( !zone->base || zone->limit == zone->base )
   2143             {
   2144               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2145                          " invoking empty subrs\n" ));
   2146               goto Syntax_Error;
   2147             }
   2148 
   2149             decoder->zone = zone;
   2150             ip            = zone->base;
   2151             limit         = zone->limit;
   2152           }
   2153           break;
   2154 
   2155         case cff_op_callgsubr:
   2156           {
   2157             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
   2158                                       decoder->globals_bias );
   2159 
   2160 
   2161             FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
   2162                         idx,
   2163                         zone - decoder->zones + 1 ));
   2164 
   2165             if ( idx >= decoder->num_globals )
   2166             {
   2167               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2168                          " invalid global subr index\n" ));
   2169               goto Syntax_Error;
   2170             }
   2171 
   2172             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
   2173             {
   2174               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2175                          " too many nested subrs\n" ));
   2176               goto Syntax_Error;
   2177             }
   2178 
   2179             zone->cursor = ip;  /* save current instruction pointer */
   2180 
   2181             zone++;
   2182             zone->base   = decoder->globals[idx];
   2183             zone->limit  = decoder->globals[idx + 1];
   2184             zone->cursor = zone->base;
   2185 
   2186             if ( !zone->base || zone->limit == zone->base )
   2187             {
   2188               FT_ERROR(( "cff_decoder_parse_charstrings:"
   2189                          " invoking empty subrs\n" ));
   2190               goto Syntax_Error;
   2191             }
   2192 
   2193             decoder->zone = zone;
   2194             ip            = zone->base;
   2195             limit         = zone->limit;
   2196           }
   2197           break;
   2198 
   2199         case cff_op_return:
   2200           FT_TRACE4(( " return (leaving level %d)\n",
   2201                       decoder->zone - decoder->zones ));
   2202 
   2203           if ( decoder->zone <= decoder->zones )
   2204           {
   2205             FT_ERROR(( "cff_decoder_parse_charstrings:"
   2206                        " unexpected return\n" ));
   2207             goto Syntax_Error;
   2208           }
   2209 
   2210           decoder->zone--;
   2211           zone  = decoder->zone;
   2212           ip    = zone->cursor;
   2213           limit = zone->limit;
   2214           break;
   2215 
   2216         default:
   2217           FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
   2218 
   2219           if ( ip[-1] == 12 )
   2220             FT_ERROR(( " %d", ip[0] ));
   2221           FT_ERROR(( "\n" ));
   2222 
   2223           return FT_THROW( Unimplemented_Feature );
   2224         }
   2225 
   2226         decoder->top = args;
   2227 
   2228         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
   2229           goto Stack_Overflow;
   2230 
   2231       } /* general operator processing */
   2232 
   2233     } /* while ip < limit */
   2234 
   2235     FT_TRACE4(( "..end..\n\n" ));
   2236 
   2237   Fail:
   2238     return error;
   2239 
   2240   MM_Error:
   2241     FT_TRACE4(( "cff_decoder_parse_charstrings:"
   2242                 " invalid opcode found in top DICT charstring\n"));
   2243     return FT_THROW( Invalid_File_Format );
   2244 
   2245   Syntax_Error:
   2246     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
   2247     return FT_THROW( Invalid_File_Format );
   2248 
   2249   Stack_Underflow:
   2250     FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
   2251     return FT_THROW( Too_Few_Arguments );
   2252 
   2253   Stack_Overflow:
   2254     FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
   2255     return FT_THROW( Stack_Overflow );
   2256   }
   2257 
   2258 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   2259 
   2260 
   2261   /**************************************************************************
   2262    *
   2263    * @Function:
   2264    *   cff_decoder_init
   2265    *
   2266    * @Description:
   2267    *   Initializes a given glyph decoder.
   2268    *
   2269    * @InOut:
   2270    *   decoder ::
   2271    *     A pointer to the glyph builder to initialize.
   2272    *
   2273    * @Input:
   2274    *   face ::
   2275    *     The current face object.
   2276    *
   2277    *   size ::
   2278    *     The current size object.
   2279    *
   2280    *   slot ::
   2281    *     The current glyph object.
   2282    *
   2283    *   hinting ::
   2284    *     Whether hinting is active.
   2285    *
   2286    *   hint_mode ::
   2287    *     The hinting mode.
   2288    */
   2289   FT_LOCAL_DEF( void )
   2290   cff_decoder_init( CFF_Decoder*                     decoder,
   2291                     TT_Face                          face,
   2292                     CFF_Size                         size,
   2293                     CFF_GlyphSlot                    slot,
   2294                     FT_Bool                          hinting,
   2295                     FT_Render_Mode                   hint_mode,
   2296                     CFF_Decoder_Get_Glyph_Callback   get_callback,
   2297                     CFF_Decoder_Free_Glyph_Callback  free_callback )
   2298   {
   2299     CFF_Font  cff = (CFF_Font)face->extra.data;
   2300 
   2301 
   2302     /* clear everything */
   2303     FT_ZERO( decoder );
   2304 
   2305     /* initialize builder */
   2306     cff_builder_init( &decoder->builder, face, size, slot, hinting );
   2307 
   2308     /* initialize Type2 decoder */
   2309     decoder->cff          = cff;
   2310     decoder->num_globals  = cff->global_subrs_index.count;
   2311     decoder->globals      = cff->global_subrs;
   2312     decoder->globals_bias = cff_compute_bias(
   2313                               cff->top_font.font_dict.charstring_type,
   2314                               decoder->num_globals );
   2315 
   2316     decoder->hint_mode = hint_mode;
   2317 
   2318     decoder->get_glyph_callback  = get_callback;
   2319     decoder->free_glyph_callback = free_callback;
   2320   }
   2321 
   2322 
   2323   /* this function is used to select the subfont */
   2324   /* and the locals subrs array                  */
   2325   FT_LOCAL_DEF( FT_Error )
   2326   cff_decoder_prepare( CFF_Decoder*  decoder,
   2327                        CFF_Size      size,
   2328                        FT_UInt       glyph_index )
   2329   {
   2330     CFF_Builder  *builder = &decoder->builder;
   2331     CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
   2332     CFF_SubFont   sub     = &cff->top_font;
   2333     FT_Error      error   = FT_Err_Ok;
   2334 
   2335     FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)cff->cffload;
   2336 
   2337 
   2338     /* manage CID fonts */
   2339     if ( cff->num_subfonts )
   2340     {
   2341       FT_Byte  fd_index = cffload->fd_select_get( &cff->fd_select,
   2342                                                   glyph_index );
   2343 
   2344 
   2345       if ( fd_index >= cff->num_subfonts )
   2346       {
   2347         FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
   2348         error = FT_THROW( Invalid_File_Format );
   2349         goto Exit;
   2350       }
   2351 
   2352       FT_TRACE3(( "  in subfont %d:\n", fd_index ));
   2353 
   2354       sub = cff->subfonts[fd_index];
   2355 
   2356       if ( builder->hints_funcs && size )
   2357       {
   2358         FT_Size       ftsize   = FT_SIZE( size );
   2359         CFF_Internal  internal = (CFF_Internal)ftsize->internal->module_data;
   2360 
   2361 
   2362         /* for CFFs without subfonts, this value has already been set */
   2363         builder->hints_globals = (void *)internal->subfonts[fd_index];
   2364       }
   2365     }
   2366 
   2367     decoder->num_locals  = sub->local_subrs_index.count;
   2368     decoder->locals      = sub->local_subrs;
   2369     decoder->locals_bias = cff_compute_bias(
   2370                              decoder->cff->top_font.font_dict.charstring_type,
   2371                              decoder->num_locals );
   2372 
   2373     decoder->glyph_width   = sub->private_dict.default_width;
   2374     decoder->nominal_width = sub->private_dict.nominal_width;
   2375 
   2376     decoder->current_subfont = sub;
   2377 
   2378   Exit:
   2379     return error;
   2380   }
   2381 
   2382 
   2383 /* END */
   2384