(root)/
freetype-2.13.2/
src/
psaux/
cffdecode.c
       1  /****************************************************************************
       2   *
       3   * cffdecode.c
       4   *
       5   *   PostScript CFF (Type 2) decoding routines (body).
       6   *
       7   * Copyright (C) 2017-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/freetype.h>
      20  #include <freetype/internal/ftdebug.h>
      21  #include <freetype/internal/ftserv.h>
      22  #include <freetype/internal/services/svcfftl.h>
      23  
      24  #include "cffdecode.h"
      25  #include "psobjs.h"
      26  
      27  #include "psauxerr.h"
      28  
      29  
      30    /**************************************************************************
      31     *
      32     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
      33     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
      34     * messages during execution.
      35     */
      36  #undef  FT_COMPONENT
      37  #define FT_COMPONENT  cffdecode
      38  
      39  
      40  #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
      41  
      42    typedef enum  CFF_Operator_
      43    {
      44      cff_op_unknown = 0,
      45  
      46      cff_op_rmoveto,
      47      cff_op_hmoveto,
      48      cff_op_vmoveto,
      49  
      50      cff_op_rlineto,
      51      cff_op_hlineto,
      52      cff_op_vlineto,
      53  
      54      cff_op_rrcurveto,
      55      cff_op_hhcurveto,
      56      cff_op_hvcurveto,
      57      cff_op_rcurveline,
      58      cff_op_rlinecurve,
      59      cff_op_vhcurveto,
      60      cff_op_vvcurveto,
      61  
      62      cff_op_flex,
      63      cff_op_hflex,
      64      cff_op_hflex1,
      65      cff_op_flex1,
      66  
      67      cff_op_endchar,
      68  
      69      cff_op_hstem,
      70      cff_op_vstem,
      71      cff_op_hstemhm,
      72      cff_op_vstemhm,
      73  
      74      cff_op_hintmask,
      75      cff_op_cntrmask,
      76      cff_op_dotsection,  /* deprecated, acts as no-op */
      77  
      78      cff_op_abs,
      79      cff_op_add,
      80      cff_op_sub,
      81      cff_op_div,
      82      cff_op_neg,
      83      cff_op_random,
      84      cff_op_mul,
      85      cff_op_sqrt,
      86  
      87      cff_op_blend,
      88  
      89      cff_op_drop,
      90      cff_op_exch,
      91      cff_op_index,
      92      cff_op_roll,
      93      cff_op_dup,
      94  
      95      cff_op_put,
      96      cff_op_get,
      97      cff_op_store,
      98      cff_op_load,
      99  
     100      cff_op_and,
     101      cff_op_or,
     102      cff_op_not,
     103      cff_op_eq,
     104      cff_op_ifelse,
     105  
     106      cff_op_callsubr,
     107      cff_op_callgsubr,
     108      cff_op_return,
     109  
     110      /* Type 1 opcodes: invalid but seen in real life */
     111      cff_op_hsbw,
     112      cff_op_closepath,
     113      cff_op_callothersubr,
     114      cff_op_pop,
     115      cff_op_seac,
     116      cff_op_sbw,
     117      cff_op_setcurrentpoint,
     118  
     119      /* do not remove */
     120      cff_op_max
     121  
     122    } CFF_Operator;
     123  
     124  
     125  #define CFF_COUNT_CHECK_WIDTH  0x80
     126  #define CFF_COUNT_EXACT        0x40
     127  #define CFF_COUNT_CLEAR_STACK  0x20
     128  
     129    /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are  */
     130    /* used for checking the width and requested numbers of arguments    */
     131    /* only; they are set to zero afterwards                             */
     132  
     133    /* the other two flags are informative only and unused currently     */
     134  
     135    static const FT_Byte  cff_argument_counts[] =
     136    {
     137      0,  /* unknown */
     138  
     139      2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
     140      1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
     141      1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
     142  
     143      0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
     144      0 | CFF_COUNT_CLEAR_STACK,
     145      0 | CFF_COUNT_CLEAR_STACK,
     146  
     147      0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
     148      0 | CFF_COUNT_CLEAR_STACK,
     149      0 | CFF_COUNT_CLEAR_STACK,
     150      0 | CFF_COUNT_CLEAR_STACK,
     151      0 | CFF_COUNT_CLEAR_STACK,
     152      0 | CFF_COUNT_CLEAR_STACK,
     153      0 | CFF_COUNT_CLEAR_STACK,
     154  
     155      13, /* flex */
     156      7,
     157      9,
     158      11,
     159  
     160      0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
     161  
     162      2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
     163      2 | CFF_COUNT_CHECK_WIDTH,
     164      2 | CFF_COUNT_CHECK_WIDTH,
     165      2 | CFF_COUNT_CHECK_WIDTH,
     166  
     167      0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
     168      0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
     169      0, /* dotsection */
     170  
     171      1, /* abs */
     172      2,
     173      2,
     174      2,
     175      1,
     176      0,
     177      2,
     178      1,
     179  
     180      1, /* blend */
     181  
     182      1, /* drop */
     183      2,
     184      1,
     185      2,
     186      1,
     187  
     188      2, /* put */
     189      1,
     190      4,
     191      3,
     192  
     193      2, /* and */
     194      2,
     195      1,
     196      2,
     197      4,
     198  
     199      1, /* callsubr */
     200      1,
     201      0,
     202  
     203      2, /* hsbw */
     204      0,
     205      0,
     206      0,
     207      5, /* seac */
     208      4, /* sbw */
     209      2  /* setcurrentpoint */
     210    };
     211  
     212  
     213    static FT_Error
     214    cff_operator_seac( CFF_Decoder*  decoder,
     215                       FT_Pos        asb,
     216                       FT_Pos        adx,
     217                       FT_Pos        ady,
     218                       FT_Int        bchar,
     219                       FT_Int        achar )
     220    {
     221      FT_Error      error;
     222      CFF_Builder*  builder = &decoder->builder;
     223      FT_Int        bchar_index, achar_index;
     224      TT_Face       face    = decoder->builder.face;
     225      FT_Vector     left_bearing, advance;
     226      FT_Byte*      charstring;
     227      FT_ULong      charstring_len;
     228      FT_Pos        glyph_width;
     229  
     230  
     231      if ( decoder->seac )
     232      {
     233        FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
     234        return FT_THROW( Syntax_Error );
     235      }
     236  
     237      adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
     238      ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
     239  
     240  #ifdef FT_CONFIG_OPTION_INCREMENTAL
     241      /* Incremental fonts don't necessarily have valid charsets.        */
     242      /* They use the character code, not the glyph index, in this case. */
     243      if ( face->root.internal->incremental_interface )
     244      {
     245        bchar_index = bchar;
     246        achar_index = achar;
     247      }
     248      else
     249  #endif /* FT_CONFIG_OPTION_INCREMENTAL */
     250      {
     251        CFF_Font cff = (CFF_Font)( face->extra.data );
     252  
     253  
     254        bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
     255        achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
     256      }
     257  
     258      if ( bchar_index < 0 || achar_index < 0 )
     259      {
     260        FT_ERROR(( "cff_operator_seac:"
     261                   " invalid seac character code arguments\n" ));
     262        return FT_THROW( Syntax_Error );
     263      }
     264  
     265      /* If we are trying to load a composite glyph, do not load the */
     266      /* accent character and return the array of subglyphs.         */
     267      if ( builder->no_recurse )
     268      {
     269        FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;
     270        FT_GlyphLoader  loader = glyph->internal->loader;
     271        FT_SubGlyph     subg;
     272  
     273  
     274        /* reallocate subglyph array if necessary */
     275        error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
     276        if ( error )
     277          goto Exit;
     278  
     279        subg = loader->current.subglyphs;
     280  
     281        /* subglyph 0 = base character */
     282        subg->index = bchar_index;
     283        subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
     284                      FT_SUBGLYPH_FLAG_USE_MY_METRICS;
     285        subg->arg1  = 0;
     286        subg->arg2  = 0;
     287        subg++;
     288  
     289        /* subglyph 1 = accent character */
     290        subg->index = achar_index;
     291        subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
     292        subg->arg1  = (FT_Int)( adx >> 16 );
     293        subg->arg2  = (FT_Int)( ady >> 16 );
     294  
     295        /* set up remaining glyph fields */
     296        glyph->num_subglyphs = 2;
     297        glyph->subglyphs     = loader->base.subglyphs;
     298        glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
     299  
     300        loader->current.num_subglyphs = 2;
     301      }
     302  
     303      FT_GlyphLoader_Prepare( builder->loader );
     304  
     305      /* First load `bchar' in builder */
     306      error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
     307                                           &charstring, &charstring_len );
     308      if ( !error )
     309      {
     310        /* the seac operator must not be nested */
     311        decoder->seac = TRUE;
     312        error = cff_decoder_parse_charstrings( decoder, charstring,
     313                                               charstring_len, 0 );
     314        decoder->seac = FALSE;
     315  
     316        decoder->free_glyph_callback( face, &charstring, charstring_len );
     317  
     318        if ( error )
     319          goto Exit;
     320      }
     321  
     322      /* Save the left bearing, advance and glyph width of the base */
     323      /* character as they will be erased by the next load.         */
     324  
     325      left_bearing = builder->left_bearing;
     326      advance      = builder->advance;
     327      glyph_width  = decoder->glyph_width;
     328  
     329      builder->left_bearing.x = 0;
     330      builder->left_bearing.y = 0;
     331  
     332      builder->pos_x = SUB_LONG( adx, asb );
     333      builder->pos_y = ady;
     334  
     335      /* Now load `achar' on top of the base outline. */
     336      error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
     337                                           &charstring, &charstring_len );
     338      if ( !error )
     339      {
     340        /* the seac operator must not be nested */
     341        decoder->seac = TRUE;
     342        error = cff_decoder_parse_charstrings( decoder, charstring,
     343                                               charstring_len, 0 );
     344        decoder->seac = FALSE;
     345  
     346        decoder->free_glyph_callback( face, &charstring, charstring_len );
     347  
     348        if ( error )
     349          goto Exit;
     350      }
     351  
     352      /* Restore the left side bearing, advance and glyph width */
     353      /* of the base character.                                 */
     354      builder->left_bearing = left_bearing;
     355      builder->advance      = advance;
     356      decoder->glyph_width  = glyph_width;
     357  
     358      builder->pos_x = 0;
     359      builder->pos_y = 0;
     360  
     361    Exit:
     362      return error;
     363    }
     364  
     365  #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
     366  
     367  
     368    /*************************************************************************/
     369    /*************************************************************************/
     370    /*************************************************************************/
     371    /**********                                                      *********/
     372    /**********                                                      *********/
     373    /**********             GENERIC CHARSTRING PARSING               *********/
     374    /**********                                                      *********/
     375    /**********                                                      *********/
     376    /*************************************************************************/
     377    /*************************************************************************/
     378    /*************************************************************************/
     379  
     380    /**************************************************************************
     381     *
     382     * @Function:
     383     *   cff_compute_bias
     384     *
     385     * @Description:
     386     *   Computes the bias value in dependence of the number of glyph
     387     *   subroutines.
     388     *
     389     * @Input:
     390     *   in_charstring_type ::
     391     *     The `CharstringType' value of the top DICT
     392     *     dictionary.
     393     *
     394     *   num_subrs ::
     395     *     The number of glyph subroutines.
     396     *
     397     * @Return:
     398     *   The bias value.
     399     */
     400    static FT_Int
     401    cff_compute_bias( FT_Int   in_charstring_type,
     402                      FT_UInt  num_subrs )
     403    {
     404      FT_Int  result;
     405  
     406  
     407      if ( in_charstring_type == 1 )
     408        result = 0;
     409      else if ( num_subrs < 1240 )
     410        result = 107;
     411      else if ( num_subrs < 33900U )
     412        result = 1131;
     413      else
     414        result = 32768U;
     415  
     416      return result;
     417    }
     418  
     419  
     420    FT_LOCAL_DEF( FT_Int )
     421    cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,
     422                                     FT_Int    charcode )
     423    {
     424      FT_UInt    n;
     425      FT_UShort  glyph_sid;
     426  
     427      FT_Service_CFFLoad  cffload;
     428  
     429  
     430      /* CID-keyed fonts don't have glyph names */
     431      if ( !cff->charset.sids )
     432        return -1;
     433  
     434      /* check range of standard char code */
     435      if ( charcode < 0 || charcode > 255 )
     436        return -1;
     437  
     438  #if 0
     439      /* retrieve cffload from list of current modules */
     440      FT_Service_CFFLoad  cffload;
     441  
     442  
     443      FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
     444      if ( !cffload )
     445      {
     446        FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
     447                   " the `cffload' module is not available\n" ));
     448        return FT_THROW( Unimplemented_Feature );
     449      }
     450  #endif
     451  
     452      cffload = (FT_Service_CFFLoad)cff->cffload;
     453  
     454      /* Get code to SID mapping from `cff_standard_encoding'. */
     455      glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
     456  
     457      for ( n = 0; n < cff->num_glyphs; n++ )
     458      {
     459        if ( cff->charset.sids[n] == glyph_sid )
     460          return (FT_Int)n;
     461      }
     462  
     463      return -1;
     464    }
     465  
     466  
     467  #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
     468  
     469    /**************************************************************************
     470     *
     471     * @Function:
     472     *   cff_decoder_parse_charstrings
     473     *
     474     * @Description:
     475     *   Parses a given Type 2 charstrings program.
     476     *
     477     * @InOut:
     478     *   decoder ::
     479     *     The current Type 1 decoder.
     480     *
     481     * @Input:
     482     *   charstring_base ::
     483     *     The base of the charstring stream.
     484     *
     485     *   charstring_len ::
     486     *     The length in bytes of the charstring stream.
     487     *
     488     *   in_dict ::
     489     *     Set to 1 if function is called from top or
     490     *     private DICT (needed for Multiple Master CFFs).
     491     *
     492     * @Return:
     493     *   FreeType error code.  0 means success.
     494     */
     495    FT_LOCAL_DEF( FT_Error )
     496    cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
     497                                   FT_Byte*      charstring_base,
     498                                   FT_ULong      charstring_len,
     499                                   FT_Bool       in_dict )
     500    {
     501      FT_Error           error;
     502      CFF_Decoder_Zone*  zone;
     503      FT_Byte*           ip;
     504      FT_Byte*           limit;
     505      CFF_Builder*       builder = &decoder->builder;
     506      FT_Pos             x, y;
     507      FT_Fixed*          stack;
     508      FT_Int             charstring_type =
     509                           decoder->cff->top_font.font_dict.charstring_type;
     510      FT_UShort          num_designs =
     511                           decoder->cff->top_font.font_dict.num_designs;
     512      FT_UShort          num_axes =
     513                           decoder->cff->top_font.font_dict.num_axes;
     514  
     515      T2_Hints_Funcs  hinter;
     516  
     517  
     518      /* set default width */
     519      decoder->num_hints  = 0;
     520      decoder->read_width = 1;
     521  
     522      /* initialize the decoder */
     523      decoder->top  = decoder->stack;
     524      decoder->zone = decoder->zones;
     525      zone          = decoder->zones;
     526      stack         = decoder->top;
     527  
     528      hinter = (T2_Hints_Funcs)builder->hints_funcs;
     529  
     530      builder->path_begun = 0;
     531  
     532      if ( !charstring_base )
     533        return FT_Err_Ok;
     534  
     535      zone->base           = charstring_base;
     536      limit = zone->limit  = charstring_base + charstring_len;
     537      ip    = zone->cursor = zone->base;
     538  
     539      error = FT_Err_Ok;
     540  
     541      x = builder->pos_x;
     542      y = builder->pos_y;
     543  
     544      /* begin hints recording session, if any */
     545      if ( hinter )
     546        hinter->open( hinter->hints );
     547  
     548      /* now execute loop */
     549      while ( ip < limit )
     550      {
     551        CFF_Operator  op;
     552        FT_Byte       v;
     553  
     554  
     555        /*********************************************************************
     556         *
     557         * Decode operator or operand
     558         */
     559        v = *ip++;
     560        if ( v >= 32 || v == 28 )
     561        {
     562          FT_Int    shift = 16;
     563          FT_Int32  val;
     564  
     565  
     566          /* this is an operand, push it on the stack */
     567  
     568          /* if we use shifts, all computations are done with unsigned */
     569          /* values; the conversion to a signed value is the last step */
     570          if ( v == 28 )
     571          {
     572            if ( ip + 1 >= limit )
     573              goto Syntax_Error;
     574            val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
     575            ip += 2;
     576          }
     577          else if ( v < 247 )
     578            val = (FT_Int32)v - 139;
     579          else if ( v < 251 )
     580          {
     581            if ( ip >= limit )
     582              goto Syntax_Error;
     583            val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
     584          }
     585          else if ( v < 255 )
     586          {
     587            if ( ip >= limit )
     588              goto Syntax_Error;
     589            val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
     590          }
     591          else
     592          {
     593            if ( ip + 3 >= limit )
     594              goto Syntax_Error;
     595            val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
     596                              ( (FT_UInt32)ip[1] << 16 ) |
     597                              ( (FT_UInt32)ip[2] <<  8 ) |
     598                                (FT_UInt32)ip[3]         );
     599            ip += 4;
     600            if ( charstring_type == 2 )
     601              shift = 0;
     602          }
     603          if ( decoder->top - stack >= CFF_MAX_OPERANDS )
     604            goto Stack_Overflow;
     605  
     606          val             = (FT_Int32)( (FT_UInt32)val << shift );
     607          *decoder->top++ = val;
     608  
     609  #ifdef FT_DEBUG_LEVEL_TRACE
     610          if ( !( val & 0xFFFFL ) )
     611            FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
     612          else
     613            FT_TRACE4(( " %.5f", val / 65536.0 ));
     614  #endif
     615  
     616        }
     617        else
     618        {
     619          /* The specification says that normally arguments are to be taken */
     620          /* from the bottom of the stack.  However, this seems not to be   */
     621          /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
     622          /* arguments similar to a PS interpreter.                         */
     623  
     624          FT_Fixed*  args     = decoder->top;
     625          FT_Int     num_args = (FT_Int)( args - decoder->stack );
     626          FT_Int     req_args;
     627  
     628  
     629          /* find operator */
     630          op = cff_op_unknown;
     631  
     632          switch ( v )
     633          {
     634          case 1:
     635            op = cff_op_hstem;
     636            break;
     637          case 3:
     638            op = cff_op_vstem;
     639            break;
     640          case 4:
     641            op = cff_op_vmoveto;
     642            break;
     643          case 5:
     644            op = cff_op_rlineto;
     645            break;
     646          case 6:
     647            op = cff_op_hlineto;
     648            break;
     649          case 7:
     650            op = cff_op_vlineto;
     651            break;
     652          case 8:
     653            op = cff_op_rrcurveto;
     654            break;
     655          case 9:
     656            op = cff_op_closepath;
     657            break;
     658          case 10:
     659            op = cff_op_callsubr;
     660            break;
     661          case 11:
     662            op = cff_op_return;
     663            break;
     664          case 12:
     665            if ( ip >= limit )
     666              goto Syntax_Error;
     667            v = *ip++;
     668  
     669            switch ( v )
     670            {
     671            case 0:
     672              op = cff_op_dotsection;
     673              break;
     674            case 1: /* this is actually the Type1 vstem3 operator */
     675              op = cff_op_vstem;
     676              break;
     677            case 2: /* this is actually the Type1 hstem3 operator */
     678              op = cff_op_hstem;
     679              break;
     680            case 3:
     681              op = cff_op_and;
     682              break;
     683            case 4:
     684              op = cff_op_or;
     685              break;
     686            case 5:
     687              op = cff_op_not;
     688              break;
     689            case 6:
     690              op = cff_op_seac;
     691              break;
     692            case 7:
     693              op = cff_op_sbw;
     694              break;
     695            case 8:
     696              op = cff_op_store;
     697              break;
     698            case 9:
     699              op = cff_op_abs;
     700              break;
     701            case 10:
     702              op = cff_op_add;
     703              break;
     704            case 11:
     705              op = cff_op_sub;
     706              break;
     707            case 12:
     708              op = cff_op_div;
     709              break;
     710            case 13:
     711              op = cff_op_load;
     712              break;
     713            case 14:
     714              op = cff_op_neg;
     715              break;
     716            case 15:
     717              op = cff_op_eq;
     718              break;
     719            case 16:
     720              op = cff_op_callothersubr;
     721              break;
     722            case 17:
     723              op = cff_op_pop;
     724              break;
     725            case 18:
     726              op = cff_op_drop;
     727              break;
     728            case 20:
     729              op = cff_op_put;
     730              break;
     731            case 21:
     732              op = cff_op_get;
     733              break;
     734            case 22:
     735              op = cff_op_ifelse;
     736              break;
     737            case 23:
     738              op = cff_op_random;
     739              break;
     740            case 24:
     741              op = cff_op_mul;
     742              break;
     743            case 26:
     744              op = cff_op_sqrt;
     745              break;
     746            case 27:
     747              op = cff_op_dup;
     748              break;
     749            case 28:
     750              op = cff_op_exch;
     751              break;
     752            case 29:
     753              op = cff_op_index;
     754              break;
     755            case 30:
     756              op = cff_op_roll;
     757              break;
     758            case 33:
     759              op = cff_op_setcurrentpoint;
     760              break;
     761            case 34:
     762              op = cff_op_hflex;
     763              break;
     764            case 35:
     765              op = cff_op_flex;
     766              break;
     767            case 36:
     768              op = cff_op_hflex1;
     769              break;
     770            case 37:
     771              op = cff_op_flex1;
     772              break;
     773            default:
     774              FT_TRACE4(( " unknown op (12, %d)\n", v ));
     775              break;
     776            }
     777            break;
     778          case 13:
     779            op = cff_op_hsbw;
     780            break;
     781          case 14:
     782            op = cff_op_endchar;
     783            break;
     784          case 16:
     785            op = cff_op_blend;
     786            break;
     787          case 18:
     788            op = cff_op_hstemhm;
     789            break;
     790          case 19:
     791            op = cff_op_hintmask;
     792            break;
     793          case 20:
     794            op = cff_op_cntrmask;
     795            break;
     796          case 21:
     797            op = cff_op_rmoveto;
     798            break;
     799          case 22:
     800            op = cff_op_hmoveto;
     801            break;
     802          case 23:
     803            op = cff_op_vstemhm;
     804            break;
     805          case 24:
     806            op = cff_op_rcurveline;
     807            break;
     808          case 25:
     809            op = cff_op_rlinecurve;
     810            break;
     811          case 26:
     812            op = cff_op_vvcurveto;
     813            break;
     814          case 27:
     815            op = cff_op_hhcurveto;
     816            break;
     817          case 29:
     818            op = cff_op_callgsubr;
     819            break;
     820          case 30:
     821            op = cff_op_vhcurveto;
     822            break;
     823          case 31:
     824            op = cff_op_hvcurveto;
     825            break;
     826          default:
     827            FT_TRACE4(( " unknown op (%d)\n", v ));
     828            break;
     829          }
     830  
     831          if ( op == cff_op_unknown )
     832            continue;
     833  
     834          /* in Multiple Master CFFs, T2 charstrings can appear in */
     835          /* dictionaries, but some operators are prohibited       */
     836          if ( in_dict )
     837          {
     838            switch ( op )
     839            {
     840            case cff_op_hstem:
     841            case cff_op_vstem:
     842            case cff_op_vmoveto:
     843            case cff_op_rlineto:
     844            case cff_op_hlineto:
     845            case cff_op_vlineto:
     846            case cff_op_rrcurveto:
     847            case cff_op_hstemhm:
     848            case cff_op_hintmask:
     849            case cff_op_cntrmask:
     850            case cff_op_rmoveto:
     851            case cff_op_hmoveto:
     852            case cff_op_vstemhm:
     853            case cff_op_rcurveline:
     854            case cff_op_rlinecurve:
     855            case cff_op_vvcurveto:
     856            case cff_op_hhcurveto:
     857            case cff_op_vhcurveto:
     858            case cff_op_hvcurveto:
     859            case cff_op_hflex:
     860            case cff_op_flex:
     861            case cff_op_hflex1:
     862            case cff_op_flex1:
     863            case cff_op_callsubr:
     864            case cff_op_callgsubr:
     865              /* deprecated opcodes */
     866            case cff_op_dotsection:
     867              /* invalid Type 1 opcodes */
     868            case cff_op_hsbw:
     869            case cff_op_closepath:
     870            case cff_op_callothersubr:
     871            case cff_op_seac:
     872            case cff_op_sbw:
     873            case cff_op_setcurrentpoint:
     874              goto MM_Error;
     875  
     876            default:
     877              break;
     878            }
     879          }
     880  
     881          /* check arguments */
     882          req_args = cff_argument_counts[op];
     883          if ( req_args & CFF_COUNT_CHECK_WIDTH )
     884          {
     885            if ( num_args > 0 && decoder->read_width )
     886            {
     887              /* If `nominal_width' is non-zero, the number is really a      */
     888              /* difference against `nominal_width'.  Else, the number here  */
     889              /* is truly a width, not a difference against `nominal_width'. */
     890              /* If the font does not set `nominal_width', then              */
     891              /* `nominal_width' defaults to zero, and so we can set         */
     892              /* `glyph_width' to `nominal_width' plus number on the stack   */
     893              /* -- for either case.                                         */
     894  
     895              FT_Int  set_width_ok;
     896  
     897  
     898              switch ( op )
     899              {
     900              case cff_op_hmoveto:
     901              case cff_op_vmoveto:
     902                set_width_ok = num_args & 2;
     903                break;
     904  
     905              case cff_op_hstem:
     906              case cff_op_vstem:
     907              case cff_op_hstemhm:
     908              case cff_op_vstemhm:
     909              case cff_op_rmoveto:
     910              case cff_op_hintmask:
     911              case cff_op_cntrmask:
     912                set_width_ok = num_args & 1;
     913                break;
     914  
     915              case cff_op_endchar:
     916                /* If there is a width specified for endchar, we either have */
     917                /* 1 argument or 5 arguments.  We like to argue.             */
     918                set_width_ok = in_dict
     919                                 ? 0
     920                                 : ( ( num_args == 5 ) || ( num_args == 1 ) );
     921                break;
     922  
     923              default:
     924                set_width_ok = 0;
     925                break;
     926              }
     927  
     928              if ( set_width_ok )
     929              {
     930                decoder->glyph_width = decoder->nominal_width +
     931                                         ( stack[0] >> 16 );
     932  
     933                if ( decoder->width_only )
     934                {
     935                  /* we only want the advance width; stop here */
     936                  break;
     937                }
     938  
     939                /* Consumed an argument. */
     940                num_args--;
     941              }
     942            }
     943  
     944            decoder->read_width = 0;
     945            req_args            = 0;
     946          }
     947  
     948          req_args &= 0x000F;
     949          if ( num_args < req_args )
     950            goto Stack_Underflow;
     951          args     -= req_args;
     952          num_args -= req_args;
     953  
     954          /* At this point, `args' points to the first argument of the  */
     955          /* operand in case `req_args' isn't zero.  Otherwise, we have */
     956          /* to adjust `args' manually.                                 */
     957  
     958          /* Note that we only pop arguments from the stack which we    */
     959          /* really need and can digest so that we can continue in case */
     960          /* of superfluous stack elements.                             */
     961  
     962          switch ( op )
     963          {
     964          case cff_op_hstem:
     965          case cff_op_vstem:
     966          case cff_op_hstemhm:
     967          case cff_op_vstemhm:
     968            /* the number of arguments is always even here */
     969            FT_TRACE4(( "%s\n",
     970                op == cff_op_hstem   ? " hstem"   :
     971              ( op == cff_op_vstem   ? " vstem"   :
     972              ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
     973  
     974            if ( hinter )
     975              hinter->stems( hinter->hints,
     976                             ( op == cff_op_hstem || op == cff_op_hstemhm ),
     977                             num_args / 2,
     978                             args - ( num_args & ~1 ) );
     979  
     980            decoder->num_hints += num_args / 2;
     981            args = stack;
     982            break;
     983  
     984          case cff_op_hintmask:
     985          case cff_op_cntrmask:
     986            FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
     987                                                    : " cntrmask" ));
     988  
     989            /* implement vstem when needed --                        */
     990            /* the specification doesn't say it, but this also works */
     991            /* with the 'cntrmask' operator                          */
     992            /*                                                       */
     993            if ( num_args > 0 )
     994            {
     995              if ( hinter )
     996                hinter->stems( hinter->hints,
     997                               0,
     998                               num_args / 2,
     999                               args - ( num_args & ~1 ) );
    1000  
    1001              decoder->num_hints += num_args / 2;
    1002            }
    1003  
    1004            /* In a valid charstring there must be at least one byte */
    1005            /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
    1006            /* instruction).  Additionally, there must be space for  */
    1007            /* `num_hints' bits.                                     */
    1008  
    1009            if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
    1010              goto Syntax_Error;
    1011  
    1012            if ( hinter )
    1013            {
    1014              if ( op == cff_op_hintmask )
    1015                hinter->hintmask( hinter->hints,
    1016                                  (FT_UInt)builder->current->n_points,
    1017                                  (FT_UInt)decoder->num_hints,
    1018                                  ip );
    1019              else
    1020                hinter->counter( hinter->hints,
    1021                                 (FT_UInt)decoder->num_hints,
    1022                                 ip );
    1023            }
    1024  
    1025  #ifdef FT_DEBUG_LEVEL_TRACE
    1026            {
    1027              FT_UInt  maskbyte;
    1028  
    1029  
    1030              FT_TRACE4(( " (maskbytes:" ));
    1031  
    1032              for ( maskbyte = 0;
    1033                    maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
    1034                    maskbyte++, ip++ )
    1035                FT_TRACE4(( " 0x%02X", *ip ));
    1036  
    1037              FT_TRACE4(( ")\n" ));
    1038            }
    1039  #else
    1040            ip += ( decoder->num_hints + 7 ) >> 3;
    1041  #endif
    1042            args = stack;
    1043            break;
    1044  
    1045          case cff_op_rmoveto:
    1046            FT_TRACE4(( " rmoveto\n" ));
    1047  
    1048            cff_builder_close_contour( builder );
    1049            builder->path_begun = 0;
    1050            x    = ADD_LONG( x, args[-2] );
    1051            y    = ADD_LONG( y, args[-1] );
    1052            args = stack;
    1053            break;
    1054  
    1055          case cff_op_vmoveto:
    1056            FT_TRACE4(( " vmoveto\n" ));
    1057  
    1058            cff_builder_close_contour( builder );
    1059            builder->path_begun = 0;
    1060            y    = ADD_LONG( y, args[-1] );
    1061            args = stack;
    1062            break;
    1063  
    1064          case cff_op_hmoveto:
    1065            FT_TRACE4(( " hmoveto\n" ));
    1066  
    1067            cff_builder_close_contour( builder );
    1068            builder->path_begun = 0;
    1069            x    = ADD_LONG( x, args[-1] );
    1070            args = stack;
    1071            break;
    1072  
    1073          case cff_op_rlineto:
    1074            FT_TRACE4(( " rlineto\n" ));
    1075  
    1076            if ( cff_builder_start_point( builder, x, y )  ||
    1077                 cff_check_points( builder, num_args / 2 ) )
    1078              goto Fail;
    1079  
    1080            if ( num_args < 2 )
    1081              goto Stack_Underflow;
    1082  
    1083            args -= num_args & ~1;
    1084            while ( args < decoder->top )
    1085            {
    1086              x = ADD_LONG( x, args[0] );
    1087              y = ADD_LONG( y, args[1] );
    1088              cff_builder_add_point( builder, x, y, 1 );
    1089              args += 2;
    1090            }
    1091            args = stack;
    1092            break;
    1093  
    1094          case cff_op_hlineto:
    1095          case cff_op_vlineto:
    1096            {
    1097              FT_Int  phase = ( op == cff_op_hlineto );
    1098  
    1099  
    1100              FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
    1101                                                       : " vlineto" ));
    1102  
    1103              if ( num_args < 0 )
    1104                goto Stack_Underflow;
    1105  
    1106              /* there exist subsetted fonts (found in PDFs) */
    1107              /* which call `hlineto' without arguments      */
    1108              if ( num_args == 0 )
    1109                break;
    1110  
    1111              if ( cff_builder_start_point( builder, x, y ) ||
    1112                   cff_check_points( builder, num_args )    )
    1113                goto Fail;
    1114  
    1115              args = stack;
    1116              while ( args < decoder->top )
    1117              {
    1118                if ( phase )
    1119                  x = ADD_LONG( x, args[0] );
    1120                else
    1121                  y = ADD_LONG( y, args[0] );
    1122  
    1123                if ( cff_builder_add_point1( builder, x, y ) )
    1124                  goto Fail;
    1125  
    1126                args++;
    1127                phase ^= 1;
    1128              }
    1129              args = stack;
    1130            }
    1131            break;
    1132  
    1133          case cff_op_rrcurveto:
    1134            {
    1135              FT_Int  nargs;
    1136  
    1137  
    1138              FT_TRACE4(( " rrcurveto\n" ));
    1139  
    1140              if ( num_args < 6 )
    1141                goto Stack_Underflow;
    1142  
    1143              nargs = num_args - num_args % 6;
    1144  
    1145              if ( cff_builder_start_point( builder, x, y ) ||
    1146                   cff_check_points( builder, nargs / 2 )   )
    1147                goto Fail;
    1148  
    1149              args -= nargs;
    1150              while ( args < decoder->top )
    1151              {
    1152                x = ADD_LONG( x, args[0] );
    1153                y = ADD_LONG( y, args[1] );
    1154                cff_builder_add_point( builder, x, y, 0 );
    1155  
    1156                x = ADD_LONG( x, args[2] );
    1157                y = ADD_LONG( y, args[3] );
    1158                cff_builder_add_point( builder, x, y, 0 );
    1159  
    1160                x = ADD_LONG( x, args[4] );
    1161                y = ADD_LONG( y, args[5] );
    1162                cff_builder_add_point( builder, x, y, 1 );
    1163  
    1164                args += 6;
    1165              }
    1166              args = stack;
    1167            }
    1168            break;
    1169  
    1170          case cff_op_vvcurveto:
    1171            {
    1172              FT_Int  nargs;
    1173  
    1174  
    1175              FT_TRACE4(( " vvcurveto\n" ));
    1176  
    1177              if ( num_args < 4 )
    1178                goto Stack_Underflow;
    1179  
    1180              /* if num_args isn't of the form 4n or 4n+1, */
    1181              /* we enforce it by clearing the second bit  */
    1182  
    1183              nargs = num_args & ~2;
    1184  
    1185              if ( cff_builder_start_point( builder, x, y ) )
    1186                goto Fail;
    1187  
    1188              args -= nargs;
    1189  
    1190              if ( nargs & 1 )
    1191              {
    1192                x = ADD_LONG( x, args[0] );
    1193                args++;
    1194                nargs--;
    1195              }
    1196  
    1197              if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
    1198                goto Fail;
    1199  
    1200              while ( args < decoder->top )
    1201              {
    1202                y = ADD_LONG( y, args[0] );
    1203                cff_builder_add_point( builder, x, y, 0 );
    1204  
    1205                x = ADD_LONG( x, args[1] );
    1206                y = ADD_LONG( y, args[2] );
    1207                cff_builder_add_point( builder, x, y, 0 );
    1208  
    1209                y = ADD_LONG( y, args[3] );
    1210                cff_builder_add_point( builder, x, y, 1 );
    1211  
    1212                args += 4;
    1213              }
    1214              args = stack;
    1215            }
    1216            break;
    1217  
    1218          case cff_op_hhcurveto:
    1219            {
    1220              FT_Int  nargs;
    1221  
    1222  
    1223              FT_TRACE4(( " hhcurveto\n" ));
    1224  
    1225              if ( num_args < 4 )
    1226                goto Stack_Underflow;
    1227  
    1228              /* if num_args isn't of the form 4n or 4n+1, */
    1229              /* we enforce it by clearing the second bit  */
    1230  
    1231              nargs = num_args & ~2;
    1232  
    1233              if ( cff_builder_start_point( builder, x, y ) )
    1234                goto Fail;
    1235  
    1236              args -= nargs;
    1237              if ( nargs & 1 )
    1238              {
    1239                y = ADD_LONG( y, args[0] );
    1240                args++;
    1241                nargs--;
    1242              }
    1243  
    1244              if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
    1245                goto Fail;
    1246  
    1247              while ( args < decoder->top )
    1248              {
    1249                x = ADD_LONG( x, args[0] );
    1250                cff_builder_add_point( builder, x, y, 0 );
    1251  
    1252                x = ADD_LONG( x, args[1] );
    1253                y = ADD_LONG( y, args[2] );
    1254                cff_builder_add_point( builder, x, y, 0 );
    1255  
    1256                x = ADD_LONG( x, args[3] );
    1257                cff_builder_add_point( builder, x, y, 1 );
    1258  
    1259                args += 4;
    1260              }
    1261              args = stack;
    1262            }
    1263            break;
    1264  
    1265          case cff_op_vhcurveto:
    1266          case cff_op_hvcurveto:
    1267            {
    1268              FT_Int  phase;
    1269              FT_Int  nargs;
    1270  
    1271  
    1272              FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
    1273                                                         : " hvcurveto" ));
    1274  
    1275              if ( cff_builder_start_point( builder, x, y ) )
    1276                goto Fail;
    1277  
    1278              if ( num_args < 4 )
    1279                goto Stack_Underflow;
    1280  
    1281              /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
    1282              /* we enforce it by clearing the second bit               */
    1283  
    1284              nargs = num_args & ~2;
    1285  
    1286              args -= nargs;
    1287              if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
    1288                goto Stack_Underflow;
    1289  
    1290              phase = ( op == cff_op_hvcurveto );
    1291  
    1292              while ( nargs >= 4 )
    1293              {
    1294                nargs -= 4;
    1295                if ( phase )
    1296                {
    1297                  x = ADD_LONG( x, args[0] );
    1298                  cff_builder_add_point( builder, x, y, 0 );
    1299  
    1300                  x = ADD_LONG( x, args[1] );
    1301                  y = ADD_LONG( y, args[2] );
    1302                  cff_builder_add_point( builder, x, y, 0 );
    1303  
    1304                  y = ADD_LONG( y, args[3] );
    1305                  if ( nargs == 1 )
    1306                    x = ADD_LONG( x, args[4] );
    1307                  cff_builder_add_point( builder, x, y, 1 );
    1308                }
    1309                else
    1310                {
    1311                  y = ADD_LONG( y, args[0] );
    1312                  cff_builder_add_point( builder, x, y, 0 );
    1313  
    1314                  x = ADD_LONG( x, args[1] );
    1315                  y = ADD_LONG( y, args[2] );
    1316                  cff_builder_add_point( builder, x, y, 0 );
    1317  
    1318                  x = ADD_LONG( x, args[3] );
    1319                  if ( nargs == 1 )
    1320                    y = ADD_LONG( y, args[4] );
    1321                  cff_builder_add_point( builder, x, y, 1 );
    1322                }
    1323                args  += 4;
    1324                phase ^= 1;
    1325              }
    1326              args = stack;
    1327            }
    1328            break;
    1329  
    1330          case cff_op_rlinecurve:
    1331            {
    1332              FT_Int  num_lines;
    1333              FT_Int  nargs;
    1334  
    1335  
    1336              FT_TRACE4(( " rlinecurve\n" ));
    1337  
    1338              if ( num_args < 8 )
    1339                goto Stack_Underflow;
    1340  
    1341              nargs     = num_args & ~1;
    1342              num_lines = ( nargs - 6 ) / 2;
    1343  
    1344              if ( cff_builder_start_point( builder, x, y )   ||
    1345                   cff_check_points( builder, num_lines + 3 ) )
    1346                goto Fail;
    1347  
    1348              args -= nargs;
    1349  
    1350              /* first, add the line segments */
    1351              while ( num_lines > 0 )
    1352              {
    1353                x = ADD_LONG( x, args[0] );
    1354                y = ADD_LONG( y, args[1] );
    1355                cff_builder_add_point( builder, x, y, 1 );
    1356  
    1357                args += 2;
    1358                num_lines--;
    1359              }
    1360  
    1361              /* then the curve */
    1362              x = ADD_LONG( x, args[0] );
    1363              y = ADD_LONG( y, args[1] );
    1364              cff_builder_add_point( builder, x, y, 0 );
    1365  
    1366              x = ADD_LONG( x, args[2] );
    1367              y = ADD_LONG( y, args[3] );
    1368              cff_builder_add_point( builder, x, y, 0 );
    1369  
    1370              x = ADD_LONG( x, args[4] );
    1371              y = ADD_LONG( y, args[5] );
    1372              cff_builder_add_point( builder, x, y, 1 );
    1373  
    1374              args = stack;
    1375            }
    1376            break;
    1377  
    1378          case cff_op_rcurveline:
    1379            {
    1380              FT_Int  num_curves;
    1381              FT_Int  nargs;
    1382  
    1383  
    1384              FT_TRACE4(( " rcurveline\n" ));
    1385  
    1386              if ( num_args < 8 )
    1387                goto Stack_Underflow;
    1388  
    1389              nargs      = num_args - 2;
    1390              nargs      = nargs - nargs % 6 + 2;
    1391              num_curves = ( nargs - 2 ) / 6;
    1392  
    1393              if ( cff_builder_start_point( builder, x, y )        ||
    1394                   cff_check_points( builder, num_curves * 3 + 2 ) )
    1395                goto Fail;
    1396  
    1397              args -= nargs;
    1398  
    1399              /* first, add the curves */
    1400              while ( num_curves > 0 )
    1401              {
    1402                x = ADD_LONG( x, args[0] );
    1403                y = ADD_LONG( y, args[1] );
    1404                cff_builder_add_point( builder, x, y, 0 );
    1405  
    1406                x = ADD_LONG( x, args[2] );
    1407                y = ADD_LONG( y, args[3] );
    1408                cff_builder_add_point( builder, x, y, 0 );
    1409  
    1410                x = ADD_LONG( x, args[4] );
    1411                y = ADD_LONG( y, args[5] );
    1412                cff_builder_add_point( builder, x, y, 1 );
    1413  
    1414                args += 6;
    1415                num_curves--;
    1416              }
    1417  
    1418              /* then the final line */
    1419              x = ADD_LONG( x, args[0] );
    1420              y = ADD_LONG( y, args[1] );
    1421              cff_builder_add_point( builder, x, y, 1 );
    1422  
    1423              args = stack;
    1424            }
    1425            break;
    1426  
    1427          case cff_op_hflex1:
    1428            {
    1429              FT_Pos  start_y;
    1430  
    1431  
    1432              FT_TRACE4(( " hflex1\n" ));
    1433  
    1434              /* adding five more points: 4 control points, 1 on-curve point */
    1435              /* -- make sure we have enough space for the start point if it */
    1436              /* needs to be added                                           */
    1437              if ( cff_builder_start_point( builder, x, y ) ||
    1438                   cff_check_points( builder, 6 )           )
    1439                goto Fail;
    1440  
    1441              /* record the starting point's y position for later use */
    1442              start_y = y;
    1443  
    1444              /* first control point */
    1445              x = ADD_LONG( x, args[0] );
    1446              y = ADD_LONG( y, args[1] );
    1447              cff_builder_add_point( builder, x, y, 0 );
    1448  
    1449              /* second control point */
    1450              x = ADD_LONG( x, args[2] );
    1451              y = ADD_LONG( y, args[3] );
    1452              cff_builder_add_point( builder, x, y, 0 );
    1453  
    1454              /* join point; on curve, with y-value the same as the last */
    1455              /* control point's y-value                                 */
    1456              x = ADD_LONG( x, args[4] );
    1457              cff_builder_add_point( builder, x, y, 1 );
    1458  
    1459              /* third control point, with y-value the same as the join */
    1460              /* point's y-value                                        */
    1461              x = ADD_LONG( x, args[5] );
    1462              cff_builder_add_point( builder, x, y, 0 );
    1463  
    1464              /* fourth control point */
    1465              x = ADD_LONG( x, args[6] );
    1466              y = ADD_LONG( y, args[7] );
    1467              cff_builder_add_point( builder, x, y, 0 );
    1468  
    1469              /* ending point, with y-value the same as the start   */
    1470              x = ADD_LONG( x, args[8] );
    1471              y = start_y;
    1472              cff_builder_add_point( builder, x, y, 1 );
    1473  
    1474              args = stack;
    1475              break;
    1476            }
    1477  
    1478          case cff_op_hflex:
    1479            {
    1480              FT_Pos  start_y;
    1481  
    1482  
    1483              FT_TRACE4(( " hflex\n" ));
    1484  
    1485              /* adding six more points; 4 control points, 2 on-curve points */
    1486              if ( cff_builder_start_point( builder, x, y ) ||
    1487                   cff_check_points( builder, 6 )           )
    1488                goto Fail;
    1489  
    1490              /* record the starting point's y-position for later use */
    1491              start_y = y;
    1492  
    1493              /* first control point */
    1494              x = ADD_LONG( x, args[0] );
    1495              cff_builder_add_point( builder, x, y, 0 );
    1496  
    1497              /* second control point */
    1498              x = ADD_LONG( x, args[1] );
    1499              y = ADD_LONG( y, args[2] );
    1500              cff_builder_add_point( builder, x, y, 0 );
    1501  
    1502              /* join point; on curve, with y-value the same as the last */
    1503              /* control point's y-value                                 */
    1504              x = ADD_LONG( x, args[3] );
    1505              cff_builder_add_point( builder, x, y, 1 );
    1506  
    1507              /* third control point, with y-value the same as the join */
    1508              /* point's y-value                                        */
    1509              x = ADD_LONG( x, args[4] );
    1510              cff_builder_add_point( builder, x, y, 0 );
    1511  
    1512              /* fourth control point */
    1513              x = ADD_LONG( x, args[5] );
    1514              y = start_y;
    1515              cff_builder_add_point( builder, x, y, 0 );
    1516  
    1517              /* ending point, with y-value the same as the start point's */
    1518              /* y-value -- we don't add this point, though               */
    1519              x = ADD_LONG( x, args[6] );
    1520              cff_builder_add_point( builder, x, y, 1 );
    1521  
    1522              args = stack;
    1523              break;
    1524            }
    1525  
    1526          case cff_op_flex1:
    1527            {
    1528              FT_Pos     start_x, start_y; /* record start x, y values for */
    1529                                           /* alter use                    */
    1530              FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
    1531                                           /* algorithm below              */
    1532              FT_Int     horizontal, count;
    1533              FT_Fixed*  temp;
    1534  
    1535  
    1536              FT_TRACE4(( " flex1\n" ));
    1537  
    1538              /* adding six more points; 4 control points, 2 on-curve points */
    1539              if ( cff_builder_start_point( builder, x, y ) ||
    1540                   cff_check_points( builder, 6 )           )
    1541                goto Fail;
    1542  
    1543              /* record the starting point's x, y position for later use */
    1544              start_x = x;
    1545              start_y = y;
    1546  
    1547              /* XXX: figure out whether this is supposed to be a horizontal */
    1548              /*      or vertical flex; the Type 2 specification is vague... */
    1549  
    1550              temp = args;
    1551  
    1552              /* grab up to the last argument */
    1553              for ( count = 5; count > 0; count-- )
    1554              {
    1555                dx    = ADD_LONG( dx, temp[0] );
    1556                dy    = ADD_LONG( dy, temp[1] );
    1557                temp += 2;
    1558              }
    1559  
    1560              if ( dx < 0 )
    1561                dx = NEG_LONG( dx );
    1562              if ( dy < 0 )
    1563                dy = NEG_LONG( dy );
    1564  
    1565              /* strange test, but here it is... */
    1566              horizontal = ( dx > dy );
    1567  
    1568              for ( count = 5; count > 0; count-- )
    1569              {
    1570                x = ADD_LONG( x, args[0] );
    1571                y = ADD_LONG( y, args[1] );
    1572                cff_builder_add_point( builder, x, y,
    1573                                       FT_BOOL( count == 3 ) );
    1574                args += 2;
    1575              }
    1576  
    1577              /* is last operand an x- or y-delta? */
    1578              if ( horizontal )
    1579              {
    1580                x = ADD_LONG( x, args[0] );
    1581                y = start_y;
    1582              }
    1583              else
    1584              {
    1585                x = start_x;
    1586                y = ADD_LONG( y, args[0] );
    1587              }
    1588  
    1589              cff_builder_add_point( builder, x, y, 1 );
    1590  
    1591              args = stack;
    1592              break;
    1593             }
    1594  
    1595          case cff_op_flex:
    1596            {
    1597              FT_UInt  count;
    1598  
    1599  
    1600              FT_TRACE4(( " flex\n" ));
    1601  
    1602              if ( cff_builder_start_point( builder, x, y ) ||
    1603                   cff_check_points( builder, 6 )           )
    1604                goto Fail;
    1605  
    1606              for ( count = 6; count > 0; count-- )
    1607              {
    1608                x = ADD_LONG( x, args[0] );
    1609                y = ADD_LONG( y, args[1] );
    1610                cff_builder_add_point( builder, x, y,
    1611                                       FT_BOOL( count == 4 || count == 1 ) );
    1612                args += 2;
    1613              }
    1614  
    1615              args = stack;
    1616            }
    1617            break;
    1618  
    1619          case cff_op_seac:
    1620            FT_TRACE4(( " seac\n" ));
    1621  
    1622            error = cff_operator_seac( decoder,
    1623                                       args[0], args[1], args[2],
    1624                                       (FT_Int)( args[3] >> 16 ),
    1625                                       (FT_Int)( args[4] >> 16 ) );
    1626  
    1627            /* add current outline to the glyph slot */
    1628            FT_GlyphLoader_Add( builder->loader );
    1629  
    1630            /* return now! */
    1631            FT_TRACE4(( "\n" ));
    1632            return error;
    1633  
    1634          case cff_op_endchar:
    1635            /* in dictionaries, `endchar' simply indicates end of data */
    1636            if ( in_dict )
    1637              return error;
    1638  
    1639            FT_TRACE4(( " endchar\n" ));
    1640  
    1641            /* We are going to emulate the seac operator. */
    1642            if ( num_args >= 4 )
    1643            {
    1644              /* Save glyph width so that the subglyphs don't overwrite it. */
    1645              FT_Pos  glyph_width = decoder->glyph_width;
    1646  
    1647  
    1648              error = cff_operator_seac( decoder,
    1649                                         0L, args[-4], args[-3],
    1650                                         (FT_Int)( args[-2] >> 16 ),
    1651                                         (FT_Int)( args[-1] >> 16 ) );
    1652  
    1653              decoder->glyph_width = glyph_width;
    1654            }
    1655            else
    1656            {
    1657              cff_builder_close_contour( builder );
    1658  
    1659              /* close hints recording session */
    1660              if ( hinter )
    1661              {
    1662                if ( hinter->close( hinter->hints,
    1663                                    (FT_UInt)builder->current->n_points ) )
    1664                  goto Syntax_Error;
    1665  
    1666                /* apply hints to the loaded glyph outline now */
    1667                error = hinter->apply( hinter->hints,
    1668                                       builder->current,
    1669                                       (PSH_Globals)builder->hints_globals,
    1670                                       decoder->hint_mode );
    1671                if ( error )
    1672                  goto Fail;
    1673              }
    1674  
    1675              /* add current outline to the glyph slot */
    1676              FT_GlyphLoader_Add( builder->loader );
    1677            }
    1678  
    1679            /* return now! */
    1680            FT_TRACE4(( "\n" ));
    1681            return error;
    1682  
    1683          case cff_op_abs:
    1684            FT_TRACE4(( " abs\n" ));
    1685  
    1686            if ( args[0] < 0 )
    1687            {
    1688              if ( args[0] == FT_LONG_MIN )
    1689                args[0] = FT_LONG_MAX;
    1690              else
    1691                args[0] = -args[0];
    1692            }
    1693            args++;
    1694            break;
    1695  
    1696          case cff_op_add:
    1697            FT_TRACE4(( " add\n" ));
    1698  
    1699            args[0] = ADD_LONG( args[0], args[1] );
    1700            args++;
    1701            break;
    1702  
    1703          case cff_op_sub:
    1704            FT_TRACE4(( " sub\n" ));
    1705  
    1706            args[0] = SUB_LONG( args[0], args[1] );
    1707            args++;
    1708            break;
    1709  
    1710          case cff_op_div:
    1711            FT_TRACE4(( " div\n" ));
    1712  
    1713            args[0] = FT_DivFix( args[0], args[1] );
    1714            args++;
    1715            break;
    1716  
    1717          case cff_op_neg:
    1718            FT_TRACE4(( " neg\n" ));
    1719  
    1720            if ( args[0] == FT_LONG_MIN )
    1721              args[0] = FT_LONG_MAX;
    1722            args[0] = -args[0];
    1723            args++;
    1724            break;
    1725  
    1726          case cff_op_random:
    1727            {
    1728              FT_UInt32*  randval = in_dict ? &decoder->cff->top_font.random
    1729                                            : &decoder->current_subfont->random;
    1730  
    1731  
    1732              FT_TRACE4(( " random\n" ));
    1733  
    1734              /* only use the lower 16 bits of `random'  */
    1735              /* to generate a number in the range (0;1] */
    1736              args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
    1737              args++;
    1738  
    1739              *randval = cff_random( *randval );
    1740            }
    1741            break;
    1742  
    1743          case cff_op_mul:
    1744            FT_TRACE4(( " mul\n" ));
    1745  
    1746            args[0] = FT_MulFix( args[0], args[1] );
    1747            args++;
    1748            break;
    1749  
    1750          case cff_op_sqrt:
    1751            FT_TRACE4(( " sqrt\n" ));
    1752  
    1753            /* without upper limit the loop below might not finish */
    1754            if ( args[0] > 0x7FFFFFFFL )
    1755              args[0] = 46341;
    1756            else if ( args[0] > 0 )
    1757            {
    1758              FT_Fixed  root = args[0];
    1759              FT_Fixed  new_root;
    1760  
    1761  
    1762              for (;;)
    1763              {
    1764                new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
    1765                if ( new_root == root )
    1766                  break;
    1767                root = new_root;
    1768              }
    1769              args[0] = new_root;
    1770            }
    1771            else
    1772              args[0] = 0;
    1773            args++;
    1774            break;
    1775  
    1776          case cff_op_drop:
    1777            /* nothing */
    1778            FT_TRACE4(( " drop\n" ));
    1779  
    1780            break;
    1781  
    1782          case cff_op_exch:
    1783            {
    1784              FT_Fixed  tmp;
    1785  
    1786  
    1787              FT_TRACE4(( " exch\n" ));
    1788  
    1789              tmp     = args[0];
    1790              args[0] = args[1];
    1791              args[1] = tmp;
    1792              args   += 2;
    1793            }
    1794            break;
    1795  
    1796          case cff_op_index:
    1797            {
    1798              FT_Int  idx = (FT_Int)( args[0] >> 16 );
    1799  
    1800  
    1801              FT_TRACE4(( " index\n" ));
    1802  
    1803              if ( idx < 0 )
    1804                idx = 0;
    1805              else if ( idx > num_args - 2 )
    1806                idx = num_args - 2;
    1807              args[0] = args[-( idx + 1 )];
    1808              args++;
    1809            }
    1810            break;
    1811  
    1812          case cff_op_roll:
    1813            {
    1814              FT_Int  count = (FT_Int)( args[0] >> 16 );
    1815              FT_Int  idx   = (FT_Int)( args[1] >> 16 );
    1816  
    1817  
    1818              FT_TRACE4(( " roll\n" ));
    1819  
    1820              if ( count <= 0 )
    1821                count = 1;
    1822  
    1823              args -= count;
    1824              if ( args < stack )
    1825                goto Stack_Underflow;
    1826  
    1827              if ( idx >= 0 )
    1828              {
    1829                idx = idx % count;
    1830                while ( idx > 0 )
    1831                {
    1832                  FT_Fixed  tmp = args[count - 1];
    1833                  FT_Int    i;
    1834  
    1835  
    1836                  for ( i = count - 2; i >= 0; i-- )
    1837                    args[i + 1] = args[i];
    1838                  args[0] = tmp;
    1839                  idx--;
    1840                }
    1841              }
    1842              else
    1843              {
    1844                /* before C99 it is implementation-defined whether    */
    1845                /* the result of `%' is negative if the first operand */
    1846                /* is negative                                        */
    1847                idx = -( NEG_INT( idx ) % count );
    1848                while ( idx < 0 )
    1849                {
    1850                  FT_Fixed  tmp = args[0];
    1851                  FT_Int    i;
    1852  
    1853  
    1854                  for ( i = 0; i < count - 1; i++ )
    1855                    args[i] = args[i + 1];
    1856                  args[count - 1] = tmp;
    1857                  idx++;
    1858                }
    1859              }
    1860              args += count;
    1861            }
    1862            break;
    1863  
    1864          case cff_op_dup:
    1865            FT_TRACE4(( " dup\n" ));
    1866  
    1867            args[1] = args[0];
    1868            args   += 2;
    1869            break;
    1870  
    1871          case cff_op_put:
    1872            {
    1873              FT_Fixed  val = args[0];
    1874              FT_UInt   idx = (FT_UInt)( args[1] >> 16 );
    1875  
    1876  
    1877              FT_TRACE4(( " put\n" ));
    1878  
    1879              /* the Type2 specification before version 16-March-2000 */
    1880              /* didn't give a hard-coded size limit of the temporary */
    1881              /* storage array; instead, an argument of the           */
    1882              /* `MultipleMaster' operator set the size               */
    1883              if ( idx < CFF_MAX_TRANS_ELEMENTS )
    1884                decoder->buildchar[idx] = val;
    1885            }
    1886            break;
    1887  
    1888          case cff_op_get:
    1889            {
    1890              FT_UInt   idx = (FT_UInt)( args[0] >> 16 );
    1891              FT_Fixed  val = 0;
    1892  
    1893  
    1894              FT_TRACE4(( " get\n" ));
    1895  
    1896              if ( idx < CFF_MAX_TRANS_ELEMENTS )
    1897                val = decoder->buildchar[idx];
    1898  
    1899              args[0] = val;
    1900              args++;
    1901            }
    1902            break;
    1903  
    1904          case cff_op_store:
    1905            /* this operator was removed from the Type2 specification */
    1906            /* in version 16-March-2000                               */
    1907  
    1908            /* since we currently don't handle interpolation of multiple */
    1909            /* master fonts, this is a no-op                             */
    1910            FT_TRACE4(( " store\n" ));
    1911            break;
    1912  
    1913          case cff_op_load:
    1914            /* this operator was removed from the Type2 specification */
    1915            /* in version 16-March-2000                               */
    1916            {
    1917              FT_UInt  reg_idx = (FT_UInt)args[0];
    1918              FT_UInt  idx     = (FT_UInt)args[1];
    1919              FT_UInt  count   = (FT_UInt)args[2];
    1920  
    1921  
    1922              FT_TRACE4(( " load\n" ));
    1923  
    1924              /* since we currently don't handle interpolation of multiple */
    1925              /* master fonts, we store a vector [1 0 0 ...] in the        */
    1926              /* temporary storage array regardless of the Registry index  */
    1927              if ( reg_idx <= 2                 &&
    1928                   idx < CFF_MAX_TRANS_ELEMENTS &&
    1929                   count <= num_axes            )
    1930              {
    1931                FT_UInt  end, i;
    1932  
    1933  
    1934                end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
    1935  
    1936                if ( idx < end )
    1937                  decoder->buildchar[idx] = 1 << 16;
    1938  
    1939                for ( i = idx + 1; i < end; i++ )
    1940                  decoder->buildchar[i] = 0;
    1941              }
    1942            }
    1943            break;
    1944  
    1945          case cff_op_blend:
    1946            /* this operator was removed from the Type2 specification */
    1947            /* in version 16-March-2000                               */
    1948            if ( num_designs )
    1949            {
    1950              FT_Int  num_results = (FT_Int)( args[0] >> 16 );
    1951  
    1952  
    1953              FT_TRACE4(( " blend\n" ));
    1954  
    1955              if ( num_results < 0 )
    1956                goto Syntax_Error;
    1957  
    1958              if ( num_results > num_args                       ||
    1959                   num_results * (FT_Int)num_designs > num_args )
    1960                goto Stack_Underflow;
    1961  
    1962              /* since we currently don't handle interpolation of multiple */
    1963              /* master fonts, return the `num_results' values of the      */
    1964              /* first master                                              */
    1965              args     -= num_results * ( num_designs - 1 );
    1966              num_args -= num_results * ( num_designs - 1 );
    1967            }
    1968            else
    1969              goto Syntax_Error;
    1970            break;
    1971  
    1972          case cff_op_dotsection:
    1973            /* this operator is deprecated and ignored by the parser */
    1974            FT_TRACE4(( " dotsection\n" ));
    1975            break;
    1976  
    1977          case cff_op_closepath:
    1978            /* this is an invalid Type 2 operator; however, there        */
    1979            /* exist fonts which are incorrectly converted from probably */
    1980            /* Type 1 to CFF, and some parsers seem to accept it         */
    1981  
    1982            FT_TRACE4(( " closepath (invalid op)\n" ));
    1983  
    1984            args = stack;
    1985            break;
    1986  
    1987          case cff_op_hsbw:
    1988            /* this is an invalid Type 2 operator; however, there        */
    1989            /* exist fonts which are incorrectly converted from probably */
    1990            /* Type 1 to CFF, and some parsers seem to accept it         */
    1991  
    1992            FT_TRACE4(( " hsbw (invalid op)\n" ));
    1993  
    1994            decoder->glyph_width =
    1995              ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
    1996  
    1997            decoder->builder.left_bearing.x = args[0];
    1998            decoder->builder.left_bearing.y = 0;
    1999  
    2000            x    = ADD_LONG( decoder->builder.pos_x, args[0] );
    2001            y    = decoder->builder.pos_y;
    2002            args = stack;
    2003            break;
    2004  
    2005          case cff_op_sbw:
    2006            /* this is an invalid Type 2 operator; however, there        */
    2007            /* exist fonts which are incorrectly converted from probably */
    2008            /* Type 1 to CFF, and some parsers seem to accept it         */
    2009  
    2010            FT_TRACE4(( " sbw (invalid op)\n" ));
    2011  
    2012            decoder->glyph_width =
    2013              ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
    2014  
    2015            decoder->builder.left_bearing.x = args[0];
    2016            decoder->builder.left_bearing.y = args[1];
    2017  
    2018            x    = ADD_LONG( decoder->builder.pos_x, args[0] );
    2019            y    = ADD_LONG( decoder->builder.pos_y, args[1] );
    2020            args = stack;
    2021            break;
    2022  
    2023          case cff_op_setcurrentpoint:
    2024            /* this is an invalid Type 2 operator; however, there        */
    2025            /* exist fonts which are incorrectly converted from probably */
    2026            /* Type 1 to CFF, and some parsers seem to accept it         */
    2027  
    2028            FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
    2029  
    2030            x    = ADD_LONG( decoder->builder.pos_x, args[0] );
    2031            y    = ADD_LONG( decoder->builder.pos_y, args[1] );
    2032            args = stack;
    2033            break;
    2034  
    2035          case cff_op_callothersubr:
    2036            {
    2037              FT_Fixed  arg;
    2038  
    2039  
    2040              /* this is an invalid Type 2 operator; however, there      */
    2041              /* exist fonts which are incorrectly converted from        */
    2042              /* probably Type 1 to CFF, and some parsers seem to accept */
    2043              /* it                                                      */
    2044  
    2045              FT_TRACE4(( " callothersubr (invalid op)\n" ));
    2046  
    2047              /* subsequent `pop' operands should add the arguments,     */
    2048              /* this is the implementation described for `unknown'      */
    2049              /* other subroutines in the Type1 spec.                    */
    2050              /*                                                         */
    2051              /* XXX Fix return arguments (see discussion below).        */
    2052  
    2053              arg = 2 + ( args[-2] >> 16 );
    2054              if ( arg >= CFF_MAX_OPERANDS )
    2055                goto Stack_Underflow;
    2056  
    2057              args -= arg;
    2058              if ( args < stack )
    2059                goto Stack_Underflow;
    2060            }
    2061            break;
    2062  
    2063          case cff_op_pop:
    2064            /* this is an invalid Type 2 operator; however, there        */
    2065            /* exist fonts which are incorrectly converted from probably */
    2066            /* Type 1 to CFF, and some parsers seem to accept it         */
    2067  
    2068            FT_TRACE4(( " pop (invalid op)\n" ));
    2069  
    2070            /* XXX Increasing `args' is wrong: After a certain number of */
    2071            /* `pop's we get a stack overflow.  Reason for doing it is   */
    2072            /* code like this (actually found in a CFF font):            */
    2073            /*                                                           */
    2074            /*   17 1 3 callothersubr                                    */
    2075            /*   pop                                                     */
    2076            /*   callsubr                                                */
    2077            /*                                                           */
    2078            /* Since we handle `callothersubr' as a no-op, and           */
    2079            /* `callsubr' needs at least one argument, `pop' can't be a  */
    2080            /* no-op too as it basically should be.                      */
    2081            /*                                                           */
    2082            /* The right solution would be to provide real support for   */
    2083            /* `callothersubr' as done in `t1decode.c', however, given   */
    2084            /* the fact that CFF fonts with `pop' are invalid, it is     */
    2085            /* questionable whether it is worth the time.                */
    2086            args++;
    2087            break;
    2088  
    2089          case cff_op_and:
    2090            {
    2091              FT_Fixed  cond = ( args[0] && args[1] );
    2092  
    2093  
    2094              FT_TRACE4(( " and\n" ));
    2095  
    2096              args[0] = cond ? 0x10000L : 0;
    2097              args++;
    2098            }
    2099            break;
    2100  
    2101          case cff_op_or:
    2102            {
    2103              FT_Fixed  cond = ( args[0] || args[1] );
    2104  
    2105  
    2106              FT_TRACE4(( " or\n" ));
    2107  
    2108              args[0] = cond ? 0x10000L : 0;
    2109              args++;
    2110            }
    2111            break;
    2112  
    2113          case cff_op_not:
    2114            {
    2115              FT_Fixed  cond = !args[0];
    2116  
    2117  
    2118              FT_TRACE4(( " not\n" ));
    2119  
    2120              args[0] = cond ? 0x10000L : 0;
    2121              args++;
    2122            }
    2123            break;
    2124  
    2125          case cff_op_eq:
    2126            {
    2127              FT_Fixed  cond = ( args[0] == args[1] );
    2128  
    2129  
    2130              FT_TRACE4(( " eq\n" ));
    2131  
    2132              args[0] = cond ? 0x10000L : 0;
    2133              args++;
    2134            }
    2135            break;
    2136  
    2137          case cff_op_ifelse:
    2138            {
    2139              FT_Fixed  cond = ( args[2] <= args[3] );
    2140  
    2141  
    2142              FT_TRACE4(( " ifelse\n" ));
    2143  
    2144              if ( !cond )
    2145                args[0] = args[1];
    2146              args++;
    2147            }
    2148            break;
    2149  
    2150          case cff_op_callsubr:
    2151            {
    2152              FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
    2153                                        decoder->locals_bias );
    2154  
    2155  
    2156              FT_TRACE4(( " callsubr (idx %d, entering level %td)\n",
    2157                          idx,
    2158                          zone - decoder->zones + 1 ));
    2159  
    2160              if ( idx >= decoder->num_locals )
    2161              {
    2162                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2163                           " invalid local subr index\n" ));
    2164                goto Syntax_Error;
    2165              }
    2166  
    2167              if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
    2168              {
    2169                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2170                           " too many nested subrs\n" ));
    2171                goto Syntax_Error;
    2172              }
    2173  
    2174              zone->cursor = ip;  /* save current instruction pointer */
    2175  
    2176              zone++;
    2177              zone->base   = decoder->locals[idx];
    2178              zone->limit  = decoder->locals[idx + 1];
    2179              zone->cursor = zone->base;
    2180  
    2181              if ( !zone->base || zone->limit == zone->base )
    2182              {
    2183                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2184                           " invoking empty subrs\n" ));
    2185                goto Syntax_Error;
    2186              }
    2187  
    2188              decoder->zone = zone;
    2189              ip            = zone->base;
    2190              limit         = zone->limit;
    2191            }
    2192            break;
    2193  
    2194          case cff_op_callgsubr:
    2195            {
    2196              FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
    2197                                        decoder->globals_bias );
    2198  
    2199  
    2200              FT_TRACE4(( " callgsubr (idx %d, entering level %td)\n",
    2201                          idx,
    2202                          zone - decoder->zones + 1 ));
    2203  
    2204              if ( idx >= decoder->num_globals )
    2205              {
    2206                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2207                           " invalid global subr index\n" ));
    2208                goto Syntax_Error;
    2209              }
    2210  
    2211              if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
    2212              {
    2213                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2214                           " too many nested subrs\n" ));
    2215                goto Syntax_Error;
    2216              }
    2217  
    2218              zone->cursor = ip;  /* save current instruction pointer */
    2219  
    2220              zone++;
    2221              zone->base   = decoder->globals[idx];
    2222              zone->limit  = decoder->globals[idx + 1];
    2223              zone->cursor = zone->base;
    2224  
    2225              if ( !zone->base || zone->limit == zone->base )
    2226              {
    2227                FT_ERROR(( "cff_decoder_parse_charstrings:"
    2228                           " invoking empty subrs\n" ));
    2229                goto Syntax_Error;
    2230              }
    2231  
    2232              decoder->zone = zone;
    2233              ip            = zone->base;
    2234              limit         = zone->limit;
    2235            }
    2236            break;
    2237  
    2238          case cff_op_return:
    2239            FT_TRACE4(( " return (leaving level %td)\n",
    2240                        decoder->zone - decoder->zones ));
    2241  
    2242            if ( decoder->zone <= decoder->zones )
    2243            {
    2244              FT_ERROR(( "cff_decoder_parse_charstrings:"
    2245                         " unexpected return\n" ));
    2246              goto Syntax_Error;
    2247            }
    2248  
    2249            decoder->zone--;
    2250            zone  = decoder->zone;
    2251            ip    = zone->cursor;
    2252            limit = zone->limit;
    2253            break;
    2254  
    2255          default:
    2256            FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
    2257  
    2258            if ( ip[-1] == 12 )
    2259              FT_ERROR(( " %d", ip[0] ));
    2260            FT_ERROR(( "\n" ));
    2261  
    2262            return FT_THROW( Unimplemented_Feature );
    2263          }
    2264  
    2265          decoder->top = args;
    2266  
    2267          if ( decoder->top - stack >= CFF_MAX_OPERANDS )
    2268            goto Stack_Overflow;
    2269  
    2270        } /* general operator processing */
    2271  
    2272      } /* while ip < limit */
    2273  
    2274      FT_TRACE4(( "..end..\n" ));
    2275      FT_TRACE4(( "\n" ));
    2276  
    2277    Fail:
    2278      return error;
    2279  
    2280    MM_Error:
    2281      FT_TRACE4(( "cff_decoder_parse_charstrings:"
    2282                  " invalid opcode found in top DICT charstring\n"));
    2283      return FT_THROW( Invalid_File_Format );
    2284  
    2285    Syntax_Error:
    2286      FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
    2287      return FT_THROW( Invalid_File_Format );
    2288  
    2289    Stack_Underflow:
    2290      FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
    2291      return FT_THROW( Too_Few_Arguments );
    2292  
    2293    Stack_Overflow:
    2294      FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
    2295      return FT_THROW( Stack_Overflow );
    2296    }
    2297  
    2298  #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
    2299  
    2300  
    2301    /**************************************************************************
    2302     *
    2303     * @Function:
    2304     *   cff_decoder_init
    2305     *
    2306     * @Description:
    2307     *   Initializes a given glyph decoder.
    2308     *
    2309     * @InOut:
    2310     *   decoder ::
    2311     *     A pointer to the glyph builder to initialize.
    2312     *
    2313     * @Input:
    2314     *   face ::
    2315     *     The current face object.
    2316     *
    2317     *   size ::
    2318     *     The current size object.
    2319     *
    2320     *   slot ::
    2321     *     The current glyph object.
    2322     *
    2323     *   hinting ::
    2324     *     Whether hinting is active.
    2325     *
    2326     *   hint_mode ::
    2327     *     The hinting mode.
    2328     */
    2329    FT_LOCAL_DEF( void )
    2330    cff_decoder_init( CFF_Decoder*                     decoder,
    2331                      TT_Face                          face,
    2332                      CFF_Size                         size,
    2333                      CFF_GlyphSlot                    slot,
    2334                      FT_Bool                          hinting,
    2335                      FT_Render_Mode                   hint_mode,
    2336                      CFF_Decoder_Get_Glyph_Callback   get_callback,
    2337                      CFF_Decoder_Free_Glyph_Callback  free_callback )
    2338    {
    2339      CFF_Font  cff = (CFF_Font)face->extra.data;
    2340  
    2341  
    2342      /* clear everything */
    2343      FT_ZERO( decoder );
    2344  
    2345      /* initialize builder */
    2346      cff_builder_init( &decoder->builder, face, size, slot, hinting );
    2347  
    2348      /* initialize Type2 decoder */
    2349      decoder->cff          = cff;
    2350      decoder->num_globals  = cff->global_subrs_index.count;
    2351      decoder->globals      = cff->global_subrs;
    2352      decoder->globals_bias = cff_compute_bias(
    2353                                cff->top_font.font_dict.charstring_type,
    2354                                decoder->num_globals );
    2355  
    2356      decoder->hint_mode = hint_mode;
    2357  
    2358      decoder->get_glyph_callback  = get_callback;
    2359      decoder->free_glyph_callback = free_callback;
    2360    }
    2361  
    2362  
    2363    /* this function is used to select the subfont */
    2364    /* and the locals subrs array                  */
    2365    FT_LOCAL_DEF( FT_Error )
    2366    cff_decoder_prepare( CFF_Decoder*  decoder,
    2367                         CFF_Size      size,
    2368                         FT_UInt       glyph_index )
    2369    {
    2370      CFF_Builder  *builder = &decoder->builder;
    2371      CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
    2372      CFF_SubFont   sub     = &cff->top_font;
    2373      FT_Error      error   = FT_Err_Ok;
    2374  
    2375      FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)cff->cffload;
    2376  
    2377  
    2378      /* manage CID fonts */
    2379      if ( cff->num_subfonts )
    2380      {
    2381        FT_Byte  fd_index = cffload->fd_select_get( &cff->fd_select,
    2382                                                    glyph_index );
    2383  
    2384  
    2385        if ( fd_index >= cff->num_subfonts )
    2386        {
    2387          FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
    2388          error = FT_THROW( Invalid_File_Format );
    2389          goto Exit;
    2390        }
    2391  
    2392        FT_TRACE3(( "  in subfont %d:\n", fd_index ));
    2393  
    2394        sub = cff->subfonts[fd_index];
    2395  
    2396        if ( builder->hints_funcs && size )
    2397        {
    2398          FT_Size       ftsize   = FT_SIZE( size );
    2399          CFF_Internal  internal = (CFF_Internal)ftsize->internal->module_data;
    2400  
    2401  
    2402          /* for CFFs without subfonts, this value has already been set */
    2403          builder->hints_globals = (void *)internal->subfonts[fd_index];
    2404        }
    2405      }
    2406  
    2407      decoder->num_locals  = sub->local_subrs_index.count;
    2408      decoder->locals      = sub->local_subrs;
    2409      decoder->locals_bias = cff_compute_bias(
    2410                               decoder->cff->top_font.font_dict.charstring_type,
    2411                               decoder->num_locals );
    2412  
    2413      decoder->glyph_width   = sub->private_dict.default_width;
    2414      decoder->nominal_width = sub->private_dict.nominal_width;
    2415  
    2416      decoder->current_subfont = sub;
    2417  
    2418    Exit:
    2419      return error;
    2420    }
    2421  
    2422  
    2423  /* END */