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