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