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