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