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