1 /****************************************************************************
   2  *
   3  * t1decode.c
   4  *
   5  *   PostScript Type 1 decoding routines (body).
   6  *
   7  * Copyright (C) 2000-2019 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_INTERNAL_CALC_H
  21 #include FT_INTERNAL_DEBUG_H
  22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
  23 #include FT_INTERNAL_HASH_H
  24 #include FT_OUTLINE_H
  25 
  26 #include "t1decode.h"
  27 #include "psobjs.h"
  28 
  29 #include "psauxerr.h"
  30 
  31 /* ensure proper sign extension */
  32 #define Fix2Int( f )  ( (FT_Int)(FT_Short)( (f) >> 16 ) )
  33 
  34   /**************************************************************************
  35    *
  36    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  37    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  38    * messages during execution.
  39    */
  40 #undef  FT_COMPONENT
  41 #define FT_COMPONENT  t1decode
  42 
  43 
  44   typedef enum  T1_Operator_
  45   {
  46     op_none = 0,
  47     op_endchar,
  48     op_hsbw,
  49     op_seac,
  50     op_sbw,
  51     op_closepath,
  52     op_hlineto,
  53     op_hmoveto,
  54     op_hvcurveto,
  55     op_rlineto,
  56     op_rmoveto,
  57     op_rrcurveto,
  58     op_vhcurveto,
  59     op_vlineto,
  60     op_vmoveto,
  61     op_dotsection,
  62     op_hstem,
  63     op_hstem3,
  64     op_vstem,
  65     op_vstem3,
  66     op_div,
  67     op_callothersubr,
  68     op_callsubr,
  69     op_pop,
  70     op_return,
  71     op_setcurrentpoint,
  72     op_unknown15,
  73 
  74     op_max    /* never remove this one */
  75 
  76   } T1_Operator;
  77 
  78 
  79   static
  80   const FT_Int  t1_args_count[op_max] =
  81   {
  82     0, /* none */
  83     0, /* endchar */
  84     2, /* hsbw */
  85     5, /* seac */
  86     4, /* sbw */
  87     0, /* closepath */
  88     1, /* hlineto */
  89     1, /* hmoveto */
  90     4, /* hvcurveto */
  91     2, /* rlineto */
  92     2, /* rmoveto */
  93     6, /* rrcurveto */
  94     4, /* vhcurveto */
  95     1, /* vlineto */
  96     1, /* vmoveto */
  97     0, /* dotsection */
  98     2, /* hstem */
  99     6, /* hstem3 */
 100     2, /* vstem */
 101     6, /* vstem3 */
 102     2, /* div */
 103    -1, /* callothersubr */
 104     1, /* callsubr */
 105     0, /* pop */
 106     0, /* return */
 107     2, /* setcurrentpoint */
 108     2  /* opcode 15 (undocumented and obsolete) */
 109   };
 110 
 111 
 112   /**************************************************************************
 113    *
 114    * @Function:
 115    *   t1_lookup_glyph_by_stdcharcode_ps
 116    *
 117    * @Description:
 118    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
 119    *   implement the SEAC Type 1 operator in the Adobe engine
 120    *
 121    * @Input:
 122    *   face ::
 123    *     The current face object.
 124    *
 125    *   charcode ::
 126    *     The character code to look for.
 127    *
 128    * @Return:
 129    *   A glyph index in the font face.  Returns -1 if the corresponding
 130    *   glyph wasn't found.
 131    */
 132   FT_LOCAL_DEF( FT_Int )
 133   t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder*  decoder,
 134                                      FT_Int       charcode )
 135   {
 136     FT_UInt             n;
 137     const FT_String*    glyph_name;
 138     FT_Service_PsCMaps  psnames = decoder->psnames;
 139 
 140 
 141     /* check range of standard char code */
 142     if ( charcode < 0 || charcode > 255 )
 143       return -1;
 144 
 145     glyph_name = psnames->adobe_std_strings(
 146                    psnames->adobe_std_encoding[charcode]);
 147 
 148     for ( n = 0; n < decoder->num_glyphs; n++ )
 149     {
 150       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 151 
 152 
 153       if ( name                               &&
 154            name[0] == glyph_name[0]           &&
 155            ft_strcmp( name, glyph_name ) == 0 )
 156         return (FT_Int)n;
 157     }
 158 
 159     return -1;
 160   }
 161 
 162 
 163 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
 164 
 165   /**************************************************************************
 166    *
 167    * @Function:
 168    *   t1_lookup_glyph_by_stdcharcode
 169    *
 170    * @Description:
 171    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
 172    *   implement the SEAC Type 1 operator.
 173    *
 174    * @Input:
 175    *   face ::
 176    *     The current face object.
 177    *
 178    *   charcode ::
 179    *     The character code to look for.
 180    *
 181    * @Return:
 182    *   A glyph index in the font face.  Returns -1 if the corresponding
 183    *   glyph wasn't found.
 184    */
 185   static FT_Int
 186   t1_lookup_glyph_by_stdcharcode( T1_Decoder  decoder,
 187                                   FT_Int      charcode )
 188   {
 189     FT_UInt             n;
 190     const FT_String*    glyph_name;
 191     FT_Service_PsCMaps  psnames = decoder->psnames;
 192 
 193 
 194     /* check range of standard char code */
 195     if ( charcode < 0 || charcode > 255 )
 196       return -1;
 197 
 198     glyph_name = psnames->adobe_std_strings(
 199                    psnames->adobe_std_encoding[charcode]);
 200 
 201     for ( n = 0; n < decoder->num_glyphs; n++ )
 202     {
 203       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 204 
 205 
 206       if ( name                               &&
 207            name[0] == glyph_name[0]           &&
 208            ft_strcmp( name, glyph_name ) == 0 )
 209         return (FT_Int)n;
 210     }
 211 
 212     return -1;
 213   }
 214 
 215 
 216   /* parse a single Type 1 glyph */
 217   FT_LOCAL_DEF( FT_Error )
 218   t1_decoder_parse_glyph( T1_Decoder  decoder,
 219                           FT_UInt     glyph )
 220   {
 221     return decoder->parse_callback( decoder, glyph );
 222   }
 223 
 224 
 225   /**************************************************************************
 226    *
 227    * @Function:
 228    *   t1operator_seac
 229    *
 230    * @Description:
 231    *   Implements the `seac' Type 1 operator for a Type 1 decoder.
 232    *
 233    * @Input:
 234    *   decoder ::
 235    *     The current CID decoder.
 236    *
 237    *   asb ::
 238    *     The accent's side bearing.
 239    *
 240    *   adx ::
 241    *     The horizontal offset of the accent.
 242    *
 243    *   ady ::
 244    *     The vertical offset of the accent.
 245    *
 246    *   bchar ::
 247    *     The base character's StandardEncoding charcode.
 248    *
 249    *   achar ::
 250    *     The accent character's StandardEncoding charcode.
 251    *
 252    * @Return:
 253    *   FreeType error code.  0 means success.
 254    */
 255   static FT_Error
 256   t1operator_seac( T1_Decoder  decoder,
 257                    FT_Pos      asb,
 258                    FT_Pos      adx,
 259                    FT_Pos      ady,
 260                    FT_Int      bchar,
 261                    FT_Int      achar )
 262   {
 263     FT_Error     error;
 264     FT_Int       bchar_index, achar_index;
 265 #if 0
 266     FT_Int       n_base_points;
 267     FT_Outline*  base = decoder->builder.base;
 268 #endif
 269     FT_Vector    left_bearing, advance;
 270 
 271 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 272     T1_Face      face  = (T1_Face)decoder->builder.face;
 273 #endif
 274 
 275 
 276     if ( decoder->seac )
 277     {
 278       FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
 279       return FT_THROW( Syntax_Error );
 280     }
 281 
 282     if ( decoder->builder.metrics_only )
 283     {
 284       FT_ERROR(( "t1operator_seac: unexpected seac\n" ));
 285       return FT_THROW( Syntax_Error );
 286     }
 287 
 288     /* seac weirdness */
 289     adx += decoder->builder.left_bearing.x;
 290 
 291     /* `glyph_names' is set to 0 for CID fonts which do not */
 292     /* include an encoding.  How can we deal with these?    */
 293 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 294     if ( decoder->glyph_names == 0                   &&
 295          !face->root.internal->incremental_interface )
 296 #else
 297     if ( decoder->glyph_names == 0 )
 298 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 299     {
 300       FT_ERROR(( "t1operator_seac:"
 301                  " glyph names table not available in this font\n" ));
 302       return FT_THROW( Syntax_Error );
 303     }
 304 
 305 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 306     if ( face->root.internal->incremental_interface )
 307     {
 308       /* the caller must handle the font encoding also */
 309       bchar_index = bchar;
 310       achar_index = achar;
 311     }
 312     else
 313 #endif
 314     {
 315       bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
 316       achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
 317     }
 318 
 319     if ( bchar_index < 0 || achar_index < 0 )
 320     {
 321       FT_ERROR(( "t1operator_seac:"
 322                  " invalid seac character code arguments\n" ));
 323       return FT_THROW( Syntax_Error );
 324     }
 325 
 326     /* if we are trying to load a composite glyph, do not load the */
 327     /* accent character and return the array of subglyphs.         */
 328     if ( decoder->builder.no_recurse )
 329     {
 330       FT_GlyphSlot    glyph  = (FT_GlyphSlot)decoder->builder.glyph;
 331       FT_GlyphLoader  loader = glyph->internal->loader;
 332       FT_SubGlyph     subg;
 333 
 334 
 335       /* reallocate subglyph array if necessary */
 336       error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
 337       if ( error )
 338         goto Exit;
 339 
 340       subg = loader->current.subglyphs;
 341 
 342       /* subglyph 0 = base character */
 343       subg->index = bchar_index;
 344       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
 345                     FT_SUBGLYPH_FLAG_USE_MY_METRICS;
 346       subg->arg1  = 0;
 347       subg->arg2  = 0;
 348       subg++;
 349 
 350       /* subglyph 1 = accent character */
 351       subg->index = achar_index;
 352       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
 353       subg->arg1  = (FT_Int)FIXED_TO_INT( adx - asb );
 354       subg->arg2  = (FT_Int)FIXED_TO_INT( ady );
 355 
 356       /* set up remaining glyph fields */
 357       glyph->num_subglyphs = 2;
 358       glyph->subglyphs     = loader->base.subglyphs;
 359       glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
 360 
 361       loader->current.num_subglyphs = 2;
 362       goto Exit;
 363     }
 364 
 365     /* First load `bchar' in builder */
 366     /* now load the unscaled outline */
 367 
 368     FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
 369 
 370     /* the seac operator must not be nested */
 371     decoder->seac = TRUE;
 372     error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
 373     decoder->seac = FALSE;
 374     if ( error )
 375       goto Exit;
 376 
 377     /* save the left bearing and width of the base character */
 378     /* as they will be erased by the next load.              */
 379 
 380     left_bearing = decoder->builder.left_bearing;
 381     advance      = decoder->builder.advance;
 382 
 383     decoder->builder.left_bearing.x = 0;
 384     decoder->builder.left_bearing.y = 0;
 385 
 386     decoder->builder.pos_x = adx - asb;
 387     decoder->builder.pos_y = ady;
 388 
 389     /* Now load `achar' on top of */
 390     /* the base outline           */
 391 
 392     /* the seac operator must not be nested */
 393     decoder->seac = TRUE;
 394     error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
 395     decoder->seac = FALSE;
 396     if ( error )
 397       goto Exit;
 398 
 399     /* restore the left side bearing and   */
 400     /* advance width of the base character */
 401 
 402     decoder->builder.left_bearing = left_bearing;
 403     decoder->builder.advance      = advance;
 404 
 405     decoder->builder.pos_x = 0;
 406     decoder->builder.pos_y = 0;
 407 
 408   Exit:
 409     return error;
 410   }
 411 
 412 
 413   /**************************************************************************
 414    *
 415    * @Function:
 416    *   t1_decoder_parse_charstrings
 417    *
 418    * @Description:
 419    *   Parses a given Type 1 charstrings program.
 420    *
 421    * @Input:
 422    *   decoder ::
 423    *     The current Type 1 decoder.
 424    *
 425    *   charstring_base ::
 426    *     The base address of the charstring stream.
 427    *
 428    *   charstring_len ::
 429    *     The length in bytes of the charstring stream.
 430    *
 431    * @Return:
 432    *   FreeType error code.  0 means success.
 433    */
 434   FT_LOCAL_DEF( FT_Error )
 435   t1_decoder_parse_charstrings( T1_Decoder  decoder,
 436                                 FT_Byte*    charstring_base,
 437                                 FT_UInt     charstring_len )
 438   {
 439     FT_Error         error;
 440     T1_Decoder_Zone  zone;
 441     FT_Byte*         ip;
 442     FT_Byte*         limit;
 443     T1_Builder       builder = &decoder->builder;
 444     FT_Pos           x, y, orig_x, orig_y;
 445     FT_Int           known_othersubr_result_cnt   = 0;
 446     FT_Int           unknown_othersubr_result_cnt = 0;
 447     FT_Bool          large_int;
 448     FT_Fixed         seed;
 449 
 450     T1_Hints_Funcs   hinter;
 451 
 452 #ifdef FT_DEBUG_LEVEL_TRACE
 453     FT_Bool          bol = TRUE;
 454 #endif
 455 
 456 
 457     /* compute random seed from stack address of parameter */
 458     seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed            ^
 459                          (FT_Offset)(char*)&decoder         ^
 460                          (FT_Offset)(char*)&charstring_base ) &
 461                          FT_ULONG_MAX                         );
 462     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
 463     if ( seed == 0 )
 464       seed = 0x7384;
 465 
 466     /* First of all, initialize the decoder */
 467     decoder->top  = decoder->stack;
 468     decoder->zone = decoder->zones;
 469     zone          = decoder->zones;
 470 
 471     builder->parse_state = T1_Parse_Start;
 472 
 473     hinter = (T1_Hints_Funcs)builder->hints_funcs;
 474 
 475     /* a font that reads BuildCharArray without setting */
 476     /* its values first is buggy, but ...               */
 477     FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
 478                ( decoder->buildchar == NULL )  );
 479 
 480     if ( decoder->buildchar && decoder->len_buildchar > 0 )
 481       FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
 482 
 483     zone->base           = charstring_base;
 484     limit = zone->limit  = charstring_base + charstring_len;
 485     ip    = zone->cursor = zone->base;
 486 
 487     error = FT_Err_Ok;
 488 
 489     x = orig_x = builder->pos_x;
 490     y = orig_y = builder->pos_y;
 491 
 492     /* begin hints recording session, if any */
 493     if ( hinter )
 494       hinter->open( hinter->hints );
 495 
 496     large_int = FALSE;
 497 
 498     /* now, execute loop */
 499     while ( ip < limit )
 500     {
 501       FT_Long*     top   = decoder->top;
 502       T1_Operator  op    = op_none;
 503       FT_Int32     value = 0;
 504 
 505 
 506       FT_ASSERT( known_othersubr_result_cnt == 0   ||
 507                  unknown_othersubr_result_cnt == 0 );
 508 
 509 #ifdef FT_DEBUG_LEVEL_TRACE
 510       if ( bol )
 511       {
 512         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
 513         bol = FALSE;
 514       }
 515 #endif
 516 
 517       /**********************************************************************
 518        *
 519        * Decode operator or operand
 520        *
 521        */
 522 
 523       /* first of all, decompress operator or value */
 524       switch ( *ip++ )
 525       {
 526       case 1:
 527         op = op_hstem;
 528         break;
 529 
 530       case 3:
 531         op = op_vstem;
 532         break;
 533       case 4:
 534         op = op_vmoveto;
 535         break;
 536       case 5:
 537         op = op_rlineto;
 538         break;
 539       case 6:
 540         op = op_hlineto;
 541         break;
 542       case 7:
 543         op = op_vlineto;
 544         break;
 545       case 8:
 546         op = op_rrcurveto;
 547         break;
 548       case 9:
 549         op = op_closepath;
 550         break;
 551       case 10:
 552         op = op_callsubr;
 553         break;
 554       case 11:
 555         op = op_return;
 556         break;
 557 
 558       case 13:
 559         op = op_hsbw;
 560         break;
 561       case 14:
 562         op = op_endchar;
 563         break;
 564 
 565       case 15:          /* undocumented, obsolete operator */
 566         op = op_unknown15;
 567         break;
 568 
 569       case 21:
 570         op = op_rmoveto;
 571         break;
 572       case 22:
 573         op = op_hmoveto;
 574         break;
 575 
 576       case 30:
 577         op = op_vhcurveto;
 578         break;
 579       case 31:
 580         op = op_hvcurveto;
 581         break;
 582 
 583       case 12:
 584         if ( ip >= limit )
 585         {
 586           FT_ERROR(( "t1_decoder_parse_charstrings:"
 587                      " invalid escape (12+EOF)\n" ));
 588           goto Syntax_Error;
 589         }
 590 
 591         switch ( *ip++ )
 592         {
 593         case 0:
 594           op = op_dotsection;
 595           break;
 596         case 1:
 597           op = op_vstem3;
 598           break;
 599         case 2:
 600           op = op_hstem3;
 601           break;
 602         case 6:
 603           op = op_seac;
 604           break;
 605         case 7:
 606           op = op_sbw;
 607           break;
 608         case 12:
 609           op = op_div;
 610           break;
 611         case 16:
 612           op = op_callothersubr;
 613           break;
 614         case 17:
 615           op = op_pop;
 616           break;
 617         case 33:
 618           op = op_setcurrentpoint;
 619           break;
 620 
 621         default:
 622           FT_ERROR(( "t1_decoder_parse_charstrings:"
 623                      " invalid escape (12+%d)\n",
 624                      ip[-1] ));
 625           goto Syntax_Error;
 626         }
 627         break;
 628 
 629       case 255:    /* four bytes integer */
 630         if ( ip + 4 > limit )
 631         {
 632           FT_ERROR(( "t1_decoder_parse_charstrings:"
 633                      " unexpected EOF in integer\n" ));
 634           goto Syntax_Error;
 635         }
 636 
 637         value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
 638                             ( (FT_UInt32)ip[1] << 16 ) |
 639                             ( (FT_UInt32)ip[2] << 8  ) |
 640                               (FT_UInt32)ip[3]         );
 641         ip += 4;
 642 
 643         /* According to the specification, values > 32000 or < -32000 must */
 644         /* be followed by a `div' operator to make the result be in the    */
 645         /* range [-32000;32000].  We expect that the second argument of    */
 646         /* `div' is not a large number.  Additionally, we don't handle     */
 647         /* stuff like `<large1> <large2> <num> div <num> div' or           */
 648         /* <large1> <large2> <num> div div'.  This is probably not allowed */
 649         /* anyway.                                                         */
 650         if ( value > 32000 || value < -32000 )
 651         {
 652           if ( large_int )
 653           {
 654             FT_ERROR(( "t1_decoder_parse_charstrings:"
 655                        " no `div' after large integer\n" ));
 656           }
 657           else
 658             large_int = TRUE;
 659         }
 660         else
 661         {
 662           if ( !large_int )
 663             value = (FT_Int32)( (FT_UInt32)value << 16 );
 664         }
 665 
 666         break;
 667 
 668       default:
 669         if ( ip[-1] >= 32 )
 670         {
 671           if ( ip[-1] < 247 )
 672             value = (FT_Int32)ip[-1] - 139;
 673           else
 674           {
 675             if ( ++ip > limit )
 676             {
 677               FT_ERROR(( "t1_decoder_parse_charstrings:"
 678                          " unexpected EOF in integer\n" ));
 679               goto Syntax_Error;
 680             }
 681 
 682             if ( ip[-2] < 251 )
 683               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
 684             else
 685               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
 686           }
 687 
 688           if ( !large_int )
 689             value = (FT_Int32)( (FT_UInt32)value << 16 );
 690         }
 691         else
 692         {
 693           FT_ERROR(( "t1_decoder_parse_charstrings:"
 694                      " invalid byte (%d)\n", ip[-1] ));
 695           goto Syntax_Error;
 696         }
 697       }
 698 
 699       if ( unknown_othersubr_result_cnt > 0 )
 700       {
 701         switch ( op )
 702         {
 703         case op_callsubr:
 704         case op_return:
 705         case op_none:
 706         case op_pop:
 707           break;
 708 
 709         default:
 710           /* all operands have been transferred by previous pops */
 711           unknown_othersubr_result_cnt = 0;
 712           break;
 713         }
 714       }
 715 
 716       if ( large_int && !( op == op_none || op == op_div ) )
 717       {
 718         FT_ERROR(( "t1_decoder_parse_charstrings:"
 719                    " no `div' after large integer\n" ));
 720 
 721         large_int = FALSE;
 722       }
 723 
 724       /**********************************************************************
 725        *
 726        * Push value on stack, or process operator
 727        *
 728        */
 729       if ( op == op_none )
 730       {
 731         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
 732         {
 733           FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
 734           goto Syntax_Error;
 735         }
 736 
 737 #ifdef FT_DEBUG_LEVEL_TRACE
 738         if ( large_int )
 739           FT_TRACE4(( " %d", value ));
 740         else
 741           FT_TRACE4(( " %d", value / 65536 ));
 742 #endif
 743 
 744         *top++       = value;
 745         decoder->top = top;
 746       }
 747       else if ( op == op_callothersubr )  /* callothersubr */
 748       {
 749         FT_Int  subr_no;
 750         FT_Int  arg_cnt;
 751 
 752 
 753 #ifdef FT_DEBUG_LEVEL_TRACE
 754         FT_TRACE4(( " callothersubr\n" ));
 755         bol = TRUE;
 756 #endif
 757 
 758         if ( top - decoder->stack < 2 )
 759           goto Stack_Underflow;
 760 
 761         top -= 2;
 762 
 763         subr_no = Fix2Int( top[1] );
 764         arg_cnt = Fix2Int( top[0] );
 765 
 766         /************************************************************
 767          *
 768          * remove all operands to callothersubr from the stack
 769          *
 770          * for handled othersubrs, where we know the number of
 771          * arguments, we increase the stack by the value of
 772          * known_othersubr_result_cnt
 773          *
 774          * for unhandled othersubrs the following pops adjust the
 775          * stack pointer as necessary
 776          */
 777 
 778         if ( arg_cnt > top - decoder->stack )
 779           goto Stack_Underflow;
 780 
 781         top -= arg_cnt;
 782 
 783         known_othersubr_result_cnt   = 0;
 784         unknown_othersubr_result_cnt = 0;
 785 
 786         /* XXX TODO: The checks to `arg_count == <whatever>'       */
 787         /* might not be correct; an othersubr expects a certain    */
 788         /* number of operands on the PostScript stack (as opposed  */
 789         /* to the T1 stack) but it doesn't have to put them there  */
 790         /* by itself; previous othersubrs might have left the      */
 791         /* operands there if they were not followed by an          */
 792         /* appropriate number of pops                              */
 793         /*                                                         */
 794         /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
 795         /* accept a font that contains charstrings like            */
 796         /*                                                         */
 797         /*     100 200 2 20 callothersubr                          */
 798         /*     300 1 20 callothersubr pop                          */
 799         /*                                                         */
 800         /* Perhaps this is the reason why BuildCharArray exists.   */
 801 
 802         switch ( subr_no )
 803         {
 804         case 0:                     /* end flex feature */
 805           if ( arg_cnt != 3 )
 806             goto Unexpected_OtherSubr;
 807 
 808           if ( !decoder->flex_state           ||
 809                decoder->num_flex_vectors != 7 )
 810           {
 811             FT_ERROR(( "t1_decoder_parse_charstrings:"
 812                        " unexpected flex end\n" ));
 813             goto Syntax_Error;
 814           }
 815 
 816           /* the two `results' are popped by the following setcurrentpoint */
 817           top[0] = x;
 818           top[1] = y;
 819           known_othersubr_result_cnt = 2;
 820           break;
 821 
 822         case 1:                     /* start flex feature */
 823           if ( arg_cnt != 0 )
 824             goto Unexpected_OtherSubr;
 825 
 826           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
 827                FT_SET_ERROR( t1_builder_check_points( builder, 6 ) )   )
 828             goto Fail;
 829 
 830           decoder->flex_state        = 1;
 831           decoder->num_flex_vectors  = 0;
 832           break;
 833 
 834         case 2:                     /* add flex vectors */
 835           {
 836             FT_Int  idx;
 837 
 838 
 839             if ( arg_cnt != 0 )
 840               goto Unexpected_OtherSubr;
 841 
 842             if ( !decoder->flex_state )
 843             {
 844               FT_ERROR(( "t1_decoder_parse_charstrings:"
 845                          " missing flex start\n" ));
 846               goto Syntax_Error;
 847             }
 848 
 849             /* note that we should not add a point for index 0; */
 850             /* this will move our current position to the flex  */
 851             /* point without adding any point to the outline    */
 852             idx = decoder->num_flex_vectors++;
 853             if ( idx > 0 && idx < 7 )
 854             {
 855               /* in malformed fonts it is possible to have other */
 856               /* opcodes in the middle of a flex (which don't    */
 857               /* increase `num_flex_vectors'); we thus have to   */
 858               /* check whether we can add a point                */
 859               if ( FT_SET_ERROR( t1_builder_check_points( builder, 1 ) ) )
 860                 goto Syntax_Error;
 861 
 862               t1_builder_add_point( builder,
 863                                     x,
 864                                     y,
 865                                     (FT_Byte)( idx == 3 || idx == 6 ) );
 866             }
 867           }
 868           break;
 869 
 870         case 3:                     /* change hints */
 871           if ( arg_cnt != 1 )
 872             goto Unexpected_OtherSubr;
 873 
 874           known_othersubr_result_cnt = 1;
 875 
 876           if ( hinter )
 877             hinter->reset( hinter->hints,
 878                            (FT_UInt)builder->current->n_points );
 879           break;
 880 
 881         case 12:
 882         case 13:
 883           /* counter control hints, clear stack */
 884           top = decoder->stack;
 885           break;
 886 
 887         case 14:
 888         case 15:
 889         case 16:
 890         case 17:
 891         case 18:                    /* multiple masters */
 892           {
 893             PS_Blend  blend = decoder->blend;
 894             FT_UInt   num_points, nn, mm;
 895             FT_Long*  delta;
 896             FT_Long*  values;
 897 
 898 
 899             if ( !blend )
 900             {
 901               FT_ERROR(( "t1_decoder_parse_charstrings:"
 902                          " unexpected multiple masters operator\n" ));
 903               goto Syntax_Error;
 904             }
 905 
 906             num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
 907             if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
 908             {
 909               FT_ERROR(( "t1_decoder_parse_charstrings:"
 910                          " incorrect number of multiple masters arguments\n" ));
 911               goto Syntax_Error;
 912             }
 913 
 914             /* We want to compute                                    */
 915             /*                                                       */
 916             /*   a0*w0 + a1*w1 + ... + ak*wk                         */
 917             /*                                                       */
 918             /* but we only have a0, a1-a0, a2-a0, ..., ak-a0.        */
 919             /*                                                       */
 920             /* However, given that w0 + w1 + ... + wk == 1, we can   */
 921             /* rewrite it easily as                                  */
 922             /*                                                       */
 923             /*   a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk     */
 924             /*                                                       */
 925             /* where k == num_designs-1.                             */
 926             /*                                                       */
 927             /* I guess that's why it's written in this `compact'     */
 928             /* form.                                                 */
 929             /*                                                       */
 930             delta  = top + num_points;
 931             values = top;
 932             for ( nn = 0; nn < num_points; nn++ )
 933             {
 934               FT_Long  tmp = values[0];
 935 
 936 
 937               for ( mm = 1; mm < blend->num_designs; mm++ )
 938                 tmp = ADD_LONG( tmp,
 939                                 FT_MulFix( *delta++,
 940                                            blend->weight_vector[mm] ) );
 941 
 942               *values++ = tmp;
 943             }
 944 
 945             known_othersubr_result_cnt = (FT_Int)num_points;
 946             break;
 947           }
 948 
 949         case 19:
 950           /* <idx> 1 19 callothersubr                             */
 951           /* => replace elements starting from index cvi( <idx> ) */
 952           /*    of BuildCharArray with WeightVector               */
 953           {
 954             FT_Int    idx;
 955             PS_Blend  blend = decoder->blend;
 956 
 957 
 958             if ( arg_cnt != 1 || !blend )
 959               goto Unexpected_OtherSubr;
 960 
 961             idx = Fix2Int( top[0] );
 962 
 963             if ( idx < 0                                                    ||
 964                  (FT_UInt)idx + blend->num_designs > decoder->len_buildchar )
 965               goto Unexpected_OtherSubr;
 966 
 967             ft_memcpy( &decoder->buildchar[idx],
 968                        blend->weight_vector,
 969                        blend->num_designs *
 970                          sizeof ( blend->weight_vector[0] ) );
 971           }
 972           break;
 973 
 974         case 20:
 975           /* <arg1> <arg2> 2 20 callothersubr pop   */
 976           /* ==> push <arg1> + <arg2> onto T1 stack */
 977           if ( arg_cnt != 2 )
 978             goto Unexpected_OtherSubr;
 979 
 980           top[0] = ADD_LONG( top[0], top[1] );
 981 
 982           known_othersubr_result_cnt = 1;
 983           break;
 984 
 985         case 21:
 986           /* <arg1> <arg2> 2 21 callothersubr pop   */
 987           /* ==> push <arg1> - <arg2> onto T1 stack */
 988           if ( arg_cnt != 2 )
 989             goto Unexpected_OtherSubr;
 990 
 991           top[0] = SUB_LONG( top[0], top[1] );
 992 
 993           known_othersubr_result_cnt = 1;
 994           break;
 995 
 996         case 22:
 997           /* <arg1> <arg2> 2 22 callothersubr pop   */
 998           /* ==> push <arg1> * <arg2> onto T1 stack */
 999           if ( arg_cnt != 2 )
1000             goto Unexpected_OtherSubr;
1001 
1002           top[0] = FT_MulFix( top[0], top[1] );
1003 
1004           known_othersubr_result_cnt = 1;
1005           break;
1006 
1007         case 23:
1008           /* <arg1> <arg2> 2 23 callothersubr pop   */
1009           /* ==> push <arg1> / <arg2> onto T1 stack */
1010           if ( arg_cnt != 2 || top[1] == 0 )
1011             goto Unexpected_OtherSubr;
1012 
1013           top[0] = FT_DivFix( top[0], top[1] );
1014 
1015           known_othersubr_result_cnt = 1;
1016           break;
1017 
1018         case 24:
1019           /* <val> <idx> 2 24 callothersubr               */
1020           /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
1021           {
1022             FT_Int    idx;
1023             PS_Blend  blend = decoder->blend;
1024 
1025 
1026             if ( arg_cnt != 2 || !blend )
1027               goto Unexpected_OtherSubr;
1028 
1029             idx = Fix2Int( top[1] );
1030 
1031             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1032               goto Unexpected_OtherSubr;
1033 
1034             decoder->buildchar[idx] = top[0];
1035           }
1036           break;
1037 
1038         case 25:
1039           /* <idx> 1 25 callothersubr pop        */
1040           /* ==> push BuildCharArray[cvi( idx )] */
1041           /*     onto T1 stack                   */
1042           {
1043             FT_Int    idx;
1044             PS_Blend  blend = decoder->blend;
1045 
1046 
1047             if ( arg_cnt != 1 || !blend )
1048               goto Unexpected_OtherSubr;
1049 
1050             idx = Fix2Int( top[0] );
1051 
1052             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1053               goto Unexpected_OtherSubr;
1054 
1055             top[0] = decoder->buildchar[idx];
1056           }
1057 
1058           known_othersubr_result_cnt = 1;
1059           break;
1060 
1061 #if 0
1062         case 26:
1063           /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
1064           /*                      leave mark on T1 stack                    */
1065           /* <val> <idx>      ==> set BuildCharArray[cvi( <idx> )] = <val>  */
1066           XXX which routine has left its mark on the (PostScript) stack?;
1067           break;
1068 #endif
1069 
1070         case 27:
1071           /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
1072           /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
1073           /*     otherwise push <res2>                          */
1074           if ( arg_cnt != 4 )
1075             goto Unexpected_OtherSubr;
1076 
1077           if ( top[2] > top[3] )
1078             top[0] = top[1];
1079 
1080           known_othersubr_result_cnt = 1;
1081           break;
1082 
1083         case 28:
1084           /* 0 28 callothersubr pop                               */
1085           /* => push random value from interval [0, 1) onto stack */
1086           if ( arg_cnt != 0 )
1087             goto Unexpected_OtherSubr;
1088 
1089           {
1090             FT_Fixed  Rand;
1091 
1092 
1093             Rand = seed;
1094             if ( Rand >= 0x8000L )
1095               Rand++;
1096 
1097             top[0] = Rand;
1098 
1099             seed = FT_MulFix( seed, 0x10000L - seed );
1100             if ( seed == 0 )
1101               seed += 0x2873;
1102           }
1103 
1104           known_othersubr_result_cnt = 1;
1105           break;
1106 
1107         default:
1108           if ( arg_cnt >= 0 && subr_no >= 0 )
1109           {
1110             FT_ERROR(( "t1_decoder_parse_charstrings:"
1111                        " unknown othersubr [%d %d], wish me luck\n",
1112                        arg_cnt, subr_no ));
1113             unknown_othersubr_result_cnt = arg_cnt;
1114             break;
1115           }
1116           /* fall through */
1117 
1118         Unexpected_OtherSubr:
1119           FT_ERROR(( "t1_decoder_parse_charstrings:"
1120                      " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
1121           goto Syntax_Error;
1122         }
1123 
1124         top += known_othersubr_result_cnt;
1125 
1126         decoder->top = top;
1127       }
1128       else  /* general operator */
1129       {
1130         FT_Int  num_args = t1_args_count[op];
1131 
1132 
1133         FT_ASSERT( num_args >= 0 );
1134 
1135         if ( top - decoder->stack < num_args )
1136           goto Stack_Underflow;
1137 
1138         /* XXX Operators usually take their operands from the        */
1139         /*     bottom of the stack, i.e., the operands are           */
1140         /*     decoder->stack[0], ..., decoder->stack[num_args - 1]; */
1141         /*     only div, callsubr, and callothersubr are different.  */
1142         /*     In practice it doesn't matter (?).                    */
1143 
1144 #ifdef FT_DEBUG_LEVEL_TRACE
1145 
1146         switch ( op )
1147         {
1148         case op_callsubr:
1149         case op_div:
1150         case op_callothersubr:
1151         case op_pop:
1152         case op_return:
1153           break;
1154 
1155         default:
1156           if ( top - decoder->stack != num_args )
1157             FT_TRACE0(( "t1_decoder_parse_charstrings:"
1158                         " too much operands on the stack"
1159                         " (seen %d, expected %d)\n",
1160                         top - decoder->stack, num_args ));
1161             break;
1162         }
1163 
1164 #endif /* FT_DEBUG_LEVEL_TRACE */
1165 
1166         top -= num_args;
1167 
1168         switch ( op )
1169         {
1170         case op_endchar:
1171           FT_TRACE4(( " endchar\n" ));
1172 
1173           t1_builder_close_contour( builder );
1174 
1175           /* close hints recording session */
1176           if ( hinter )
1177           {
1178             if ( hinter->close( hinter->hints,
1179                                 (FT_UInt)builder->current->n_points ) )
1180               goto Syntax_Error;
1181 
1182             /* apply hints to the loaded glyph outline now */
1183             error = hinter->apply( hinter->hints,
1184                                    builder->current,
1185                                    (PSH_Globals)builder->hints_globals,
1186                                    decoder->hint_mode );
1187             if ( error )
1188               goto Fail;
1189           }
1190 
1191           /* add current outline to the glyph slot */
1192           FT_GlyphLoader_Add( builder->loader );
1193 
1194           /* the compiler should optimize away this empty loop but ... */
1195 
1196 #ifdef FT_DEBUG_LEVEL_TRACE
1197 
1198           if ( decoder->len_buildchar > 0 )
1199           {
1200             FT_UInt  i;
1201 
1202 
1203             FT_TRACE4(( "BuildCharArray = [ " ));
1204 
1205             for ( i = 0; i < decoder->len_buildchar; i++ )
1206               FT_TRACE4(( "%d ", decoder->buildchar[i] ));
1207 
1208             FT_TRACE4(( "]\n" ));
1209           }
1210 
1211 #endif /* FT_DEBUG_LEVEL_TRACE */
1212 
1213           FT_TRACE4(( "\n" ));
1214 
1215           /* return now! */
1216           return FT_Err_Ok;
1217 
1218         case op_hsbw:
1219           FT_TRACE4(( " hsbw" ));
1220 
1221           builder->parse_state = T1_Parse_Have_Width;
1222 
1223           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1224                                               top[0] );
1225 
1226           builder->advance.x = top[1];
1227           builder->advance.y = 0;
1228 
1229           orig_x = x = ADD_LONG( builder->pos_x, top[0] );
1230           orig_y = y = builder->pos_y;
1231 
1232           FT_UNUSED( orig_y );
1233 
1234           /* the `metrics_only' indicates that we only want to compute */
1235           /* the glyph's metrics (lsb + advance width), not load the   */
1236           /* rest of it; so exit immediately                           */
1237           if ( builder->metrics_only )
1238           {
1239             FT_TRACE4(( "\n" ));
1240             return FT_Err_Ok;
1241           }
1242 
1243           break;
1244 
1245         case op_seac:
1246           return t1operator_seac( decoder,
1247                                   top[0],
1248                                   top[1],
1249                                   top[2],
1250                                   Fix2Int( top[3] ),
1251                                   Fix2Int( top[4] ) );
1252 
1253         case op_sbw:
1254           FT_TRACE4(( " sbw" ));
1255 
1256           builder->parse_state = T1_Parse_Have_Width;
1257 
1258           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1259                                               top[0] );
1260           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1261                                               top[1] );
1262 
1263           builder->advance.x = top[2];
1264           builder->advance.y = top[3];
1265 
1266           x = ADD_LONG( builder->pos_x, top[0] );
1267           y = ADD_LONG( builder->pos_y, top[1] );
1268 
1269           /* the `metrics_only' indicates that we only want to compute */
1270           /* the glyph's metrics (lsb + advance width), not load the   */
1271           /* rest of it; so exit immediately                           */
1272           if ( builder->metrics_only )
1273           {
1274             FT_TRACE4(( "\n" ));
1275             return FT_Err_Ok;
1276           }
1277 
1278           break;
1279 
1280         case op_closepath:
1281           FT_TRACE4(( " closepath" ));
1282 
1283           /* if there is no path, `closepath' is a no-op */
1284           if ( builder->parse_state == T1_Parse_Have_Path   ||
1285                builder->parse_state == T1_Parse_Have_Moveto )
1286             t1_builder_close_contour( builder );
1287 
1288           builder->parse_state = T1_Parse_Have_Width;
1289           break;
1290 
1291         case op_hlineto:
1292           FT_TRACE4(( " hlineto" ));
1293 
1294           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1295             goto Fail;
1296 
1297           x = ADD_LONG( x, top[0] );
1298           goto Add_Line;
1299 
1300         case op_hmoveto:
1301           FT_TRACE4(( " hmoveto" ));
1302 
1303           x = ADD_LONG( x, top[0] );
1304 
1305           if ( !decoder->flex_state )
1306           {
1307             if ( builder->parse_state == T1_Parse_Start )
1308               goto Syntax_Error;
1309             builder->parse_state = T1_Parse_Have_Moveto;
1310           }
1311           break;
1312 
1313         case op_hvcurveto:
1314           FT_TRACE4(( " hvcurveto" ));
1315 
1316           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1317                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1318             goto Fail;
1319 
1320           x = ADD_LONG( x, top[0] );
1321           t1_builder_add_point( builder, x, y, 0 );
1322 
1323           x = ADD_LONG( x, top[1] );
1324           y = ADD_LONG( y, top[2] );
1325           t1_builder_add_point( builder, x, y, 0 );
1326 
1327           y = ADD_LONG( y, top[3] );
1328           t1_builder_add_point( builder, x, y, 1 );
1329           break;
1330 
1331         case op_rlineto:
1332           FT_TRACE4(( " rlineto" ));
1333 
1334           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1335             goto Fail;
1336 
1337           x = ADD_LONG( x, top[0] );
1338           y = ADD_LONG( y, top[1] );
1339 
1340         Add_Line:
1341           if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
1342             goto Fail;
1343           break;
1344 
1345         case op_rmoveto:
1346           FT_TRACE4(( " rmoveto" ));
1347 
1348           x = ADD_LONG( x, top[0] );
1349           y = ADD_LONG( y, top[1] );
1350 
1351           if ( !decoder->flex_state )
1352           {
1353             if ( builder->parse_state == T1_Parse_Start )
1354               goto Syntax_Error;
1355             builder->parse_state = T1_Parse_Have_Moveto;
1356           }
1357           break;
1358 
1359         case op_rrcurveto:
1360           FT_TRACE4(( " rrcurveto" ));
1361 
1362           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1363                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1364             goto Fail;
1365 
1366           x = ADD_LONG( x, top[0] );
1367           y = ADD_LONG( y, top[1] );
1368           t1_builder_add_point( builder, x, y, 0 );
1369 
1370           x = ADD_LONG( x, top[2] );
1371           y = ADD_LONG( y, top[3] );
1372           t1_builder_add_point( builder, x, y, 0 );
1373 
1374           x = ADD_LONG( x, top[4] );
1375           y = ADD_LONG( y, top[5] );
1376           t1_builder_add_point( builder, x, y, 1 );
1377           break;
1378 
1379         case op_vhcurveto:
1380           FT_TRACE4(( " vhcurveto" ));
1381 
1382           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1383                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1384             goto Fail;
1385 
1386           y = ADD_LONG( y, top[0] );
1387           t1_builder_add_point( builder, x, y, 0 );
1388 
1389           x = ADD_LONG( x, top[1] );
1390           y = ADD_LONG( y, top[2] );
1391           t1_builder_add_point( builder, x, y, 0 );
1392 
1393           x = ADD_LONG( x, top[3] );
1394           t1_builder_add_point( builder, x, y, 1 );
1395           break;
1396 
1397         case op_vlineto:
1398           FT_TRACE4(( " vlineto" ));
1399 
1400           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1401             goto Fail;
1402 
1403           y = ADD_LONG( y, top[0] );
1404           goto Add_Line;
1405 
1406         case op_vmoveto:
1407           FT_TRACE4(( " vmoveto" ));
1408 
1409           y = ADD_LONG( y, top[0] );
1410 
1411           if ( !decoder->flex_state )
1412           {
1413             if ( builder->parse_state == T1_Parse_Start )
1414               goto Syntax_Error;
1415             builder->parse_state = T1_Parse_Have_Moveto;
1416           }
1417           break;
1418 
1419         case op_div:
1420           FT_TRACE4(( " div" ));
1421 
1422           /* if `large_int' is set, we divide unscaled numbers; */
1423           /* otherwise, we divide numbers in 16.16 format --    */
1424           /* in both cases, it is the same operation            */
1425           *top = FT_DivFix( top[0], top[1] );
1426           top++;
1427 
1428           large_int = FALSE;
1429           break;
1430 
1431         case op_callsubr:
1432           {
1433             FT_Int  idx;
1434 
1435 
1436             FT_TRACE4(( " callsubr" ));
1437 
1438             idx = Fix2Int( top[0] );
1439 
1440             if ( decoder->subrs_hash )
1441             {
1442               size_t*  val = ft_hash_num_lookup( idx,
1443                                                  decoder->subrs_hash );
1444 
1445 
1446               if ( val )
1447                 idx = *val;
1448               else
1449                 idx = -1;
1450             }
1451 
1452             if ( idx < 0 || idx >= decoder->num_subrs )
1453             {
1454               FT_ERROR(( "t1_decoder_parse_charstrings:"
1455                          " invalid subrs index\n" ));
1456               goto Syntax_Error;
1457             }
1458 
1459             if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
1460             {
1461               FT_ERROR(( "t1_decoder_parse_charstrings:"
1462                          " too many nested subrs\n" ));
1463               goto Syntax_Error;
1464             }
1465 
1466             zone->cursor = ip;  /* save current instruction pointer */
1467 
1468             zone++;
1469 
1470             /* The Type 1 driver stores subroutines without the seed bytes. */
1471             /* The CID driver stores subroutines with seed bytes.  This     */
1472             /* case is taken care of when decoder->subrs_len == 0.          */
1473             zone->base = decoder->subrs[idx];
1474 
1475             if ( decoder->subrs_len )
1476               zone->limit = zone->base + decoder->subrs_len[idx];
1477             else
1478             {
1479               /* We are using subroutines from a CID font.  We must adjust */
1480               /* for the seed bytes.                                       */
1481               zone->base  += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
1482               zone->limit  = decoder->subrs[idx + 1];
1483             }
1484 
1485             zone->cursor = zone->base;
1486 
1487             if ( !zone->base )
1488             {
1489               FT_ERROR(( "t1_decoder_parse_charstrings:"
1490                          " invoking empty subrs\n" ));
1491               goto Syntax_Error;
1492             }
1493 
1494             decoder->zone = zone;
1495             ip            = zone->base;
1496             limit         = zone->limit;
1497             break;
1498           }
1499 
1500         case op_pop:
1501           FT_TRACE4(( " pop" ));
1502 
1503           if ( known_othersubr_result_cnt > 0 )
1504           {
1505             known_othersubr_result_cnt--;
1506             /* ignore, we pushed the operands ourselves */
1507             break;
1508           }
1509 
1510           if ( unknown_othersubr_result_cnt == 0 )
1511           {
1512             FT_ERROR(( "t1_decoder_parse_charstrings:"
1513                        " no more operands for othersubr\n" ));
1514             goto Syntax_Error;
1515           }
1516 
1517           unknown_othersubr_result_cnt--;
1518           top++;   /* `push' the operand to callothersubr onto the stack */
1519           break;
1520 
1521         case op_return:
1522           FT_TRACE4(( " return" ));
1523 
1524           if ( zone <= decoder->zones )
1525           {
1526             FT_ERROR(( "t1_decoder_parse_charstrings:"
1527                        " unexpected return\n" ));
1528             goto Syntax_Error;
1529           }
1530 
1531           zone--;
1532           ip            = zone->cursor;
1533           limit         = zone->limit;
1534           decoder->zone = zone;
1535           break;
1536 
1537         case op_dotsection:
1538           FT_TRACE4(( " dotsection" ));
1539 
1540           break;
1541 
1542         case op_hstem:
1543           FT_TRACE4(( " hstem" ));
1544 
1545           /* record horizontal hint */
1546           if ( hinter )
1547           {
1548             /* top[0] += builder->left_bearing.y; */
1549             hinter->stem( hinter->hints, 1, top );
1550           }
1551           break;
1552 
1553         case op_hstem3:
1554           FT_TRACE4(( " hstem3" ));
1555 
1556           /* record horizontal counter-controlled hints */
1557           if ( hinter )
1558             hinter->stem3( hinter->hints, 1, top );
1559           break;
1560 
1561         case op_vstem:
1562           FT_TRACE4(( " vstem" ));
1563 
1564           /* record vertical hint */
1565           if ( hinter )
1566           {
1567             top[0] = ADD_LONG( top[0], orig_x );
1568             hinter->stem( hinter->hints, 0, top );
1569           }
1570           break;
1571 
1572         case op_vstem3:
1573           FT_TRACE4(( " vstem3" ));
1574 
1575           /* record vertical counter-controlled hints */
1576           if ( hinter )
1577           {
1578             FT_Pos  dx = orig_x;
1579 
1580 
1581             top[0] = ADD_LONG( top[0], dx );
1582             top[2] = ADD_LONG( top[2], dx );
1583             top[4] = ADD_LONG( top[4], dx );
1584             hinter->stem3( hinter->hints, 0, top );
1585           }
1586           break;
1587 
1588         case op_setcurrentpoint:
1589           FT_TRACE4(( " setcurrentpoint" ));
1590 
1591           /* From the T1 specification, section 6.4:                */
1592           /*                                                        */
1593           /*   The setcurrentpoint command is used only in          */
1594           /*   conjunction with results from OtherSubrs procedures. */
1595 
1596           /* known_othersubr_result_cnt != 0 is already handled     */
1597           /* above.                                                 */
1598 
1599           /* Note, however, that both Ghostscript and Adobe         */
1600           /* Distiller handle this situation by silently ignoring   */
1601           /* the inappropriate `setcurrentpoint' instruction.  So   */
1602           /* we do the same.                                        */
1603 #if 0
1604 
1605           if ( decoder->flex_state != 1 )
1606           {
1607             FT_ERROR(( "t1_decoder_parse_charstrings:"
1608                        " unexpected `setcurrentpoint'\n" ));
1609             goto Syntax_Error;
1610           }
1611           else
1612             ...
1613 #endif
1614 
1615           x = top[0];
1616           y = top[1];
1617           decoder->flex_state = 0;
1618           break;
1619 
1620         case op_unknown15:
1621           FT_TRACE4(( " opcode_15" ));
1622           /* nothing to do except to pop the two arguments */
1623           break;
1624 
1625         default:
1626           FT_ERROR(( "t1_decoder_parse_charstrings:"
1627                      " unhandled opcode %d\n", op ));
1628           goto Syntax_Error;
1629         }
1630 
1631         /* XXX Operators usually clear the operand stack;  */
1632         /*     only div, callsubr, callothersubr, pop, and */
1633         /*     return are different.                       */
1634         /*     In practice it doesn't matter (?).          */
1635 
1636         decoder->top = top;
1637 
1638 #ifdef FT_DEBUG_LEVEL_TRACE
1639         FT_TRACE4(( "\n" ));
1640         bol = TRUE;
1641 #endif
1642 
1643       } /* general operator processing */
1644 
1645     } /* while ip < limit */
1646 
1647     FT_TRACE4(( "..end..\n\n" ));
1648 
1649   Fail:
1650     return error;
1651 
1652   Syntax_Error:
1653     return FT_THROW( Syntax_Error );
1654 
1655   Stack_Underflow:
1656     return FT_THROW( Stack_Underflow );
1657   }
1658 
1659 
1660 #else /* !T1_CONFIG_OPTION_OLD_ENGINE */
1661 
1662 
1663   /**************************************************************************
1664    *
1665    * @Function:
1666    *   t1_decoder_parse_metrics
1667    *
1668    * @Description:
1669    *   Parses a given Type 1 charstrings program to extract width
1670    *
1671    * @Input:
1672    *   decoder ::
1673    *     The current Type 1 decoder.
1674    *
1675    *   charstring_base ::
1676    *     The base address of the charstring stream.
1677    *
1678    *   charstring_len ::
1679    *     The length in bytes of the charstring stream.
1680    *
1681    * @Return:
1682    *   FreeType error code.  0 means success.
1683    */
1684   FT_LOCAL_DEF( FT_Error )
1685   t1_decoder_parse_metrics( T1_Decoder  decoder,
1686                             FT_Byte*    charstring_base,
1687                             FT_UInt     charstring_len )
1688   {
1689     T1_Decoder_Zone  zone;
1690     FT_Byte*         ip;
1691     FT_Byte*         limit;
1692     T1_Builder       builder = &decoder->builder;
1693 
1694 #ifdef FT_DEBUG_LEVEL_TRACE
1695     FT_Bool          bol = TRUE;
1696 #endif
1697 
1698 
1699     /* First of all, initialize the decoder */
1700     decoder->top  = decoder->stack;
1701     decoder->zone = decoder->zones;
1702     zone          = decoder->zones;
1703 
1704     builder->parse_state = T1_Parse_Start;
1705 
1706     zone->base           = charstring_base;
1707     limit = zone->limit  = charstring_base + charstring_len;
1708     ip    = zone->cursor = zone->base;
1709 
1710     /* now, execute loop */
1711     while ( ip < limit )
1712     {
1713       FT_Long*     top   = decoder->top;
1714       T1_Operator  op    = op_none;
1715       FT_Int32     value = 0;
1716 
1717 
1718 #ifdef FT_DEBUG_LEVEL_TRACE
1719       if ( bol )
1720       {
1721         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
1722         bol = FALSE;
1723       }
1724 #endif
1725 
1726       /**********************************************************************
1727        *
1728        * Decode operator or operand
1729        *
1730        */
1731 
1732       /* first of all, decompress operator or value */
1733       switch ( *ip++ )
1734       {
1735       case 1:
1736       case 3:
1737       case 4:
1738       case 5:
1739       case 6:
1740       case 7:
1741       case 8:
1742       case 9:
1743       case 10:
1744       case 11:
1745       case 14:
1746       case 15:
1747       case 21:
1748       case 22:
1749       case 30:
1750       case 31:
1751         goto No_Width;
1752 
1753       case 13:
1754         op = op_hsbw;
1755         break;
1756 
1757       case 12:
1758         if ( ip >= limit )
1759         {
1760           FT_ERROR(( "t1_decoder_parse_metrics:"
1761                      " invalid escape (12+EOF)\n" ));
1762           goto Syntax_Error;
1763         }
1764 
1765         switch ( *ip++ )
1766         {
1767         case 7:
1768           op = op_sbw;
1769           break;
1770 
1771         default:
1772           goto No_Width;
1773         }
1774         break;
1775 
1776       case 255:    /* four bytes integer */
1777         if ( ip + 4 > limit )
1778         {
1779           FT_ERROR(( "t1_decoder_parse_metrics:"
1780                      " unexpected EOF in integer\n" ));
1781           goto Syntax_Error;
1782         }
1783 
1784         value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
1785                             ( (FT_UInt32)ip[1] << 16 ) |
1786                             ( (FT_UInt32)ip[2] << 8  ) |
1787                               (FT_UInt32)ip[3]         );
1788         ip += 4;
1789 
1790         /* According to the specification, values > 32000 or < -32000 must */
1791         /* be followed by a `div' operator to make the result be in the    */
1792         /* range [-32000;32000].  We expect that the second argument of    */
1793         /* `div' is not a large number.  Additionally, we don't handle     */
1794         /* stuff like `<large1> <large2> <num> div <num> div' or           */
1795         /* <large1> <large2> <num> div div'.  This is probably not allowed */
1796         /* anyway.                                                         */
1797         if ( value > 32000 || value < -32000 )
1798         {
1799           FT_ERROR(( "t1_decoder_parse_metrics:"
1800                      " large integer found for width\n" ));
1801           goto Syntax_Error;
1802         }
1803         else
1804         {
1805           value = (FT_Int32)( (FT_UInt32)value << 16 );
1806         }
1807 
1808         break;
1809 
1810       default:
1811         if ( ip[-1] >= 32 )
1812         {
1813           if ( ip[-1] < 247 )
1814             value = (FT_Int32)ip[-1] - 139;
1815           else
1816           {
1817             if ( ++ip > limit )
1818             {
1819               FT_ERROR(( "t1_decoder_parse_metrics:"
1820                          " unexpected EOF in integer\n" ));
1821               goto Syntax_Error;
1822             }
1823 
1824             if ( ip[-2] < 251 )
1825               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
1826             else
1827               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
1828           }
1829 
1830           value = (FT_Int32)( (FT_UInt32)value << 16 );
1831         }
1832         else
1833         {
1834           FT_ERROR(( "t1_decoder_parse_metrics:"
1835                      " invalid byte (%d)\n", ip[-1] ));
1836           goto Syntax_Error;
1837         }
1838       }
1839 
1840       /**********************************************************************
1841        *
1842        * Push value on stack, or process operator
1843        *
1844        */
1845       if ( op == op_none )
1846       {
1847         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
1848         {
1849           FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
1850           goto Syntax_Error;
1851         }
1852 
1853 #ifdef FT_DEBUG_LEVEL_TRACE
1854           FT_TRACE4(( " %d", value / 65536 ));
1855 #endif
1856 
1857         *top++       = value;
1858         decoder->top = top;
1859       }
1860       else  /* general operator */
1861       {
1862         FT_Int  num_args = t1_args_count[op];
1863 
1864 
1865         FT_ASSERT( num_args >= 0 );
1866 
1867         if ( top - decoder->stack < num_args )
1868           goto Stack_Underflow;
1869 
1870 #ifdef FT_DEBUG_LEVEL_TRACE
1871 
1872         if ( top - decoder->stack != num_args )
1873           FT_TRACE0(( "t1_decoder_parse_metrics:"
1874                       " too much operands on the stack"
1875                       " (seen %d, expected %d)\n",
1876                       top - decoder->stack, num_args ));
1877 
1878 #endif /* FT_DEBUG_LEVEL_TRACE */
1879 
1880         top -= num_args;
1881 
1882         switch ( op )
1883         {
1884         case op_hsbw:
1885           FT_TRACE4(( " hsbw" ));
1886 
1887           builder->parse_state = T1_Parse_Have_Width;
1888 
1889           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1890                                               top[0] );
1891 
1892           builder->advance.x = top[1];
1893           builder->advance.y = 0;
1894 
1895           /* we only want to compute the glyph's metrics */
1896           /* (lsb + advance width), not load the rest of */
1897           /* it; so exit immediately                     */
1898           FT_TRACE4(( "\n" ));
1899           return FT_Err_Ok;
1900 
1901         case op_sbw:
1902           FT_TRACE4(( " sbw" ));
1903 
1904           builder->parse_state = T1_Parse_Have_Width;
1905 
1906           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1907                                               top[0] );
1908           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1909                                               top[1] );
1910 
1911           builder->advance.x = top[2];
1912           builder->advance.y = top[3];
1913 
1914           /* we only want to compute the glyph's metrics */
1915           /* (lsb + advance width), not load the rest of */
1916           /* it; so exit immediately                     */
1917           FT_TRACE4(( "\n" ));
1918           return FT_Err_Ok;
1919 
1920         default:
1921           FT_ERROR(( "t1_decoder_parse_metrics:"
1922                      " unhandled opcode %d\n", op ));
1923           goto Syntax_Error;
1924         }
1925 
1926       } /* general operator processing */
1927 
1928     } /* while ip < limit */
1929 
1930     FT_TRACE4(( "..end..\n\n" ));
1931 
1932   No_Width:
1933     FT_ERROR(( "t1_decoder_parse_metrics:"
1934                " no width, found op %d instead\n",
1935                ip[-1] ));
1936   Syntax_Error:
1937     return FT_THROW( Syntax_Error );
1938 
1939   Stack_Underflow:
1940     return FT_THROW( Stack_Underflow );
1941   }
1942 
1943 #endif /* !T1_CONFIG_OPTION_OLD_ENGINE */
1944 
1945 
1946   /* initialize T1 decoder */
1947   FT_LOCAL_DEF( FT_Error )
1948   t1_decoder_init( T1_Decoder           decoder,
1949                    FT_Face              face,
1950                    FT_Size              size,
1951                    FT_GlyphSlot         slot,
1952                    FT_Byte**            glyph_names,
1953                    PS_Blend             blend,
1954                    FT_Bool              hinting,
1955                    FT_Render_Mode       hint_mode,
1956                    T1_Decoder_Callback  parse_callback )
1957   {
1958     FT_ZERO( decoder );
1959 
1960     /* retrieve `psnames' interface from list of current modules */
1961     {
1962       FT_Service_PsCMaps  psnames;
1963 
1964 
1965       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1966       if ( !psnames )
1967       {
1968         FT_ERROR(( "t1_decoder_init:"
1969                    " the `psnames' module is not available\n" ));
1970         return FT_THROW( Unimplemented_Feature );
1971       }
1972 
1973       decoder->psnames = psnames;
1974     }
1975 
1976     t1_builder_init( &decoder->builder, face, size, slot, hinting );
1977 
1978     /* decoder->buildchar and decoder->len_buildchar have to be  */
1979     /* initialized by the caller since we cannot know the length */
1980     /* of the BuildCharArray                                     */
1981 
1982     decoder->num_glyphs     = (FT_UInt)face->num_glyphs;
1983     decoder->glyph_names    = glyph_names;
1984     decoder->hint_mode      = hint_mode;
1985     decoder->blend          = blend;
1986     decoder->parse_callback = parse_callback;
1987 
1988     decoder->funcs          = t1_decoder_funcs;
1989 
1990     return FT_Err_Ok;
1991   }
1992 
1993 
1994   /* finalize T1 decoder */
1995   FT_LOCAL_DEF( void )
1996   t1_decoder_done( T1_Decoder  decoder )
1997   {
1998     FT_Memory  memory = decoder->builder.memory;
1999 
2000 
2001     t1_builder_done( &decoder->builder );
2002 
2003     if ( decoder->cf2_instance.finalizer )
2004     {
2005       decoder->cf2_instance.finalizer( decoder->cf2_instance.data );
2006       FT_FREE( decoder->cf2_instance.data );
2007     }
2008   }
2009 
2010 
2011 /* END */