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