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