| Index: third_party/freetype/src/truetype/ttinterp.c
 | 
| diff --git a/third_party/freetype/src/truetype/ttinterp.c b/third_party/freetype/src/truetype/ttinterp.c
 | 
| index 6bdffbca52762b0515f8ae9bf0adf8089cea965c..ae2a82adc5ede6a1206fbd8482237d9d8cbab309 100644
 | 
| --- a/third_party/freetype/src/truetype/ttinterp.c
 | 
| +++ b/third_party/freetype/src/truetype/ttinterp.c
 | 
| @@ -4,8 +4,8 @@
 | 
|  /*                                                                         */
 | 
|  /*    TrueType bytecode interpreter (body).                                */
 | 
|  /*                                                                         */
 | 
| -/*  Copyright 1996-2014                                                    */
 | 
| -/*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */
 | 
| +/*  Copyright 1996-2015 by                                                 */
 | 
| +/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 | 
|  /*                                                                         */
 | 
|  /*  This file is part of the FreeType project, and may only be used,       */
 | 
|  /*  modified, and distributed under the terms of the FreeType project      */
 | 
| @@ -44,6 +44,7 @@
 | 
|  #undef  FT_COMPONENT
 | 
|  #define FT_COMPONENT  trace_ttinterp
 | 
|  
 | 
| +
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
|    /* In order to detect infinite loops in the code, we set up a counter    */
 | 
| @@ -53,174 +54,30 @@
 | 
|  #define MAX_RUNNABLE_OPCODES  1000000L
 | 
|  
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* There are two kinds of implementations:                               */
 | 
| -  /*                                                                       */
 | 
| -  /* a. static implementation                                              */
 | 
| -  /*                                                                       */
 | 
| -  /*    The current execution context is a static variable, which fields   */
 | 
| -  /*    are accessed directly by the interpreter during execution.  The    */
 | 
| -  /*    context is named `cur'.                                            */
 | 
| -  /*                                                                       */
 | 
| -  /*    This version is non-reentrant, of course.                          */
 | 
| -  /*                                                                       */
 | 
| -  /* b. indirect implementation                                            */
 | 
| -  /*                                                                       */
 | 
| -  /*    The current execution context is passed to _each_ function as its  */
 | 
| -  /*    first argument, and each field is thus accessed indirectly.        */
 | 
| -  /*                                                                       */
 | 
| -  /*    This version is fully re-entrant.                                  */
 | 
| -  /*                                                                       */
 | 
| -  /* The idea is that an indirect implementation may be slower to execute  */
 | 
| -  /* on low-end processors that are used in some systems (like 386s or     */
 | 
| -  /* even 486s).                                                           */
 | 
| -  /*                                                                       */
 | 
| -  /* As a consequence, the indirect implementation is now the default, as  */
 | 
| -  /* its performance costs can be considered negligible in our context.    */
 | 
| -  /* Note, however, that we kept the same source with macros because:      */
 | 
| -  /*                                                                       */
 | 
| -  /* - The code is kept very close in design to the Pascal code used for   */
 | 
| -  /*   development.                                                        */
 | 
| -  /*                                                                       */
 | 
| -  /* - It's much more readable that way!                                   */
 | 
| -  /*                                                                       */
 | 
| -  /* - It's still open to experimentation and tuning.                      */
 | 
| -  /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| -
 | 
| -
 | 
| -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */
 | 
| -
 | 
| -#define CUR  (*exc)                             /* see ttobjs.h */
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* This macro is used whenever `exec' is unused in a function, to avoid  */
 | 
| -  /* stupid warnings from pedantic compilers.                              */
 | 
| -  /*                                                                       */
 | 
| -#define FT_UNUSED_EXEC  FT_UNUSED( exc )
 | 
| -
 | 
| -#else                                           /* static implementation */
 | 
| -
 | 
| -#define CUR  cur
 | 
| -
 | 
| -#define FT_UNUSED_EXEC  int  __dummy = __dummy
 | 
| -
 | 
| -  static
 | 
| -  TT_ExecContextRec  cur;   /* static exec. context variable */
 | 
| -
 | 
| -  /* apparently, we have a _lot_ of direct indexing when accessing  */
 | 
| -  /* the static `cur', which makes the code bigger (due to all the  */
 | 
| -  /* four bytes addresses).                                         */
 | 
| -
 | 
| -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* The instruction argument stack.                                       */
 | 
| -  /*                                                                       */
 | 
| -#define INS_ARG  EXEC_OP_ FT_Long*  args    /* see ttobjs.h for EXEC_OP_ */
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* This macro is used whenever `args' is unused in a function, to avoid  */
 | 
| -  /* stupid warnings from pedantic compilers.                              */
 | 
| -  /*                                                                       */
 | 
| -#define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )
 | 
| -
 | 
| -
 | 
| -#define SUBPIXEL_HINTING                                                    \
 | 
| -          ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
 | 
| +#define SUBPIXEL_HINTING                                                     \
 | 
| +          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
 | 
|              TT_INTERPRETER_VERSION_38 )
 | 
|  
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
 | 
| -  /* increase readability of the code.                                     */
 | 
| -  /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| -
 | 
| -
 | 
| -#define SKIP_Code() \
 | 
| -          SkipCode( EXEC_ARG )
 | 
| -
 | 
| -#define GET_ShortIns() \
 | 
| -          GetShortIns( EXEC_ARG )
 | 
| -
 | 
| -#define NORMalize( x, y, v ) \
 | 
| -          Normalize( EXEC_ARG_ x, y, v )
 | 
| -
 | 
| -#define SET_SuperRound( scale, flags ) \
 | 
| -          SetSuperRound( EXEC_ARG_ scale, flags )
 | 
| -
 | 
| -#define ROUND_None( d, c ) \
 | 
| -          Round_None( EXEC_ARG_ d, c )
 | 
| -
 | 
| -#define INS_Goto_CodeRange( range, ip ) \
 | 
| -          Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
 | 
| -
 | 
| -#define CUR_Func_move( z, p, d ) \
 | 
| -          CUR.func_move( EXEC_ARG_ z, p, d )
 | 
| -
 | 
| -#define CUR_Func_move_orig( z, p, d ) \
 | 
| -          CUR.func_move_orig( EXEC_ARG_ z, p, d )
 | 
| -
 | 
| -#define CUR_Func_round( d, c ) \
 | 
| -          CUR.func_round( EXEC_ARG_ d, c )
 | 
| -
 | 
| -#define CUR_Func_cur_ppem() \
 | 
| -          CUR.func_cur_ppem( EXEC_ARG )
 | 
| -
 | 
| -#define CUR_Func_read_cvt( index ) \
 | 
| -          CUR.func_read_cvt( EXEC_ARG_ index )
 | 
| -
 | 
| -#define CUR_Func_write_cvt( index, val ) \
 | 
| -          CUR.func_write_cvt( EXEC_ARG_ index, val )
 | 
| -
 | 
| -#define CUR_Func_move_cvt( index, val ) \
 | 
| -          CUR.func_move_cvt( EXEC_ARG_ index, val )
 | 
| -
 | 
| -#define CURRENT_Ratio() \
 | 
| -          Current_Ratio( EXEC_ARG )
 | 
| -
 | 
| -#define INS_SxVTL( a, b, c, d ) \
 | 
| -          Ins_SxVTL( EXEC_ARG_ a, b, c, d )
 | 
| -
 | 
| -#define COMPUTE_Funcs() \
 | 
| -          Compute_Funcs( EXEC_ARG )
 | 
| -
 | 
| -#define COMPUTE_Round( a ) \
 | 
| -          Compute_Round( EXEC_ARG_ a )
 | 
| +#define PROJECT( v1, v2 )                                                \
 | 
| +          exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 | 
|  
 | 
| -#define COMPUTE_Point_Displacement( a, b, c, d ) \
 | 
| -          Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
 | 
| +#define DUALPROJ( v1, v2 )                                                \
 | 
| +          exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 | 
|  
 | 
| -#define MOVE_Zp2_Point( a, b, c, t ) \
 | 
| -          Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
 | 
| +#define FAST_PROJECT( v )                          \
 | 
| +          exc->func_project( exc, (v)->x, (v)->y )
 | 
|  
 | 
| -
 | 
| -#define CUR_Func_project( v1, v2 )  \
 | 
| -          CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 | 
| -
 | 
| -#define CUR_Func_dualproj( v1, v2 )  \
 | 
| -          CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 | 
| -
 | 
| -#define CUR_fast_project( v ) \
 | 
| -          CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
 | 
| -
 | 
| -#define CUR_fast_dualproj( v ) \
 | 
| -          CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
 | 
| +#define FAST_DUALPROJ( v )                          \
 | 
| +          exc->func_dualproj( exc, (v)->x, (v)->y )
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
|    /* Instruction dispatch function, as used by the interpreter.            */
 | 
|    /*                                                                       */
 | 
| -  typedef void  (*TInstruction_Function)( INS_ARG );
 | 
| +  typedef void  (*TInstruction_Function)( TT_ExecContext  exc,
 | 
| +                                          FT_Long*        args );
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
| @@ -230,13 +87,6 @@
 | 
|  #define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )
 | 
|  #define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* This macro computes (a*2^14)/b and complements TT_MulFix14.           */
 | 
| -  /*                                                                       */
 | 
| -#define TT_DivFix14( a, b ) \
 | 
| -          FT_DivFix( a, (b) << 2 )
 | 
| -
 | 
|  
 | 
|  #undef  SUCCESS
 | 
|  #define SUCCESS  0
 | 
| @@ -245,16 +95,20 @@
 | 
|  #define FAILURE  1
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -#define GUESS_VECTOR( V )                                         \
 | 
| -  if ( CUR.face->unpatented_hinting )                             \
 | 
| -  {                                                               \
 | 
| -    CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
 | 
| -    CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
 | 
| -  }
 | 
| +#define GUESS_VECTOR( V )                                             \
 | 
| +  do                                                                  \
 | 
| +  {                                                                   \
 | 
| +    if ( exc->face->unpatented_hinting )                              \
 | 
| +    {                                                                 \
 | 
| +      exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
 | 
| +      exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
 | 
| +    }                                                                 \
 | 
| +  } while (0)
 | 
|  #else
 | 
| -#define GUESS_VECTOR( V )
 | 
| +#define GUESS_VECTOR( V )  do { } while (0)
 | 
|  #endif
 | 
|  
 | 
| +
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
|    /*                        CODERANGE FUNCTIONS                            */
 | 
| @@ -297,7 +151,7 @@
 | 
|      /*       which will return to the first byte *after* the code    */
 | 
|      /*       range, we test for IP <= Size instead of IP < Size.     */
 | 
|      /*                                                               */
 | 
| -    FT_ASSERT( (FT_ULong)IP <= coderange->size );
 | 
| +    FT_ASSERT( IP <= coderange->size );
 | 
|  
 | 
|      exec->code     = coderange->base;
 | 
|      exec->codeSize = coderange->size;
 | 
| @@ -498,7 +352,7 @@
 | 
|    FT_LOCAL_DEF( FT_Error )
 | 
|    Update_Max( FT_Memory  memory,
 | 
|                FT_ULong*  size,
 | 
| -              FT_Long    multiplier,
 | 
| +              FT_ULong   multiplier,
 | 
|                void*      _pbuff,
 | 
|                FT_ULong   new_max )
 | 
|    {
 | 
| @@ -591,13 +445,13 @@
 | 
|  
 | 
|      /* XXX: We reserve a little more elements on the stack to deal safely */
 | 
|      /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
 | 
| -    tmp = exec->stackSize;
 | 
| +    tmp = (FT_ULong)exec->stackSize;
 | 
|      error = Update_Max( exec->memory,
 | 
|                          &tmp,
 | 
|                          sizeof ( FT_F26Dot6 ),
 | 
|                          (void*)&exec->stack,
 | 
|                          maxp->maxStackElements + 32 );
 | 
| -    exec->stackSize = (FT_UInt)tmp;
 | 
| +    exec->stackSize = (FT_Long)tmp;
 | 
|      if ( error )
 | 
|        return error;
 | 
|  
 | 
| @@ -683,12 +537,8 @@
 | 
|    /* <Return>                                                              */
 | 
|    /*    TrueType error code.  0 means success.                             */
 | 
|    /*                                                                       */
 | 
| -  /* <Note>                                                                */
 | 
| -  /*    Only the glyph loader and debugger should call this function.      */
 | 
| -  /*                                                                       */
 | 
|    FT_LOCAL_DEF( FT_Error )
 | 
| -  TT_Run_Context( TT_ExecContext  exec,
 | 
| -                  FT_Bool         debug )
 | 
| +  TT_Run_Context( TT_ExecContext  exec )
 | 
|    {
 | 
|      TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
 | 
|  
 | 
| @@ -718,16 +568,7 @@
 | 
|      exec->top     = 0;
 | 
|      exec->callTop = 0;
 | 
|  
 | 
| -#if 1
 | 
| -    FT_UNUSED( debug );
 | 
| -
 | 
|      return exec->face->interpreter( exec );
 | 
| -#else
 | 
| -    if ( !debug )
 | 
| -      return TT_RunIns( exec );
 | 
| -    else
 | 
| -      return FT_Err_Ok;
 | 
| -#endif
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -761,6 +602,9 @@
 | 
|    TT_New_Context( TT_Driver  driver )
 | 
|    {
 | 
|      FT_Memory  memory;
 | 
| +    FT_Error   error;
 | 
| +
 | 
| +    TT_ExecContext  exec = NULL;
 | 
|  
 | 
|  
 | 
|      if ( !driver )
 | 
| @@ -768,26 +612,16 @@
 | 
|  
 | 
|      memory = driver->root.root.memory;
 | 
|  
 | 
| -    if ( !driver->context )
 | 
| -    {
 | 
| -      FT_Error        error;
 | 
| -      TT_ExecContext  exec;
 | 
| -
 | 
| -
 | 
| -      /* allocate object */
 | 
| -      if ( FT_NEW( exec ) )
 | 
| -        goto Fail;
 | 
| -
 | 
| -      /* initialize it; in case of error this deallocates `exec' too */
 | 
| -      error = Init_Context( exec, memory );
 | 
| -      if ( error )
 | 
| -        goto Fail;
 | 
| +    /* allocate object */
 | 
| +    if ( FT_NEW( exec ) )
 | 
| +      goto Fail;
 | 
|  
 | 
| -      /* store it into the driver */
 | 
| -      driver->context = exec;
 | 
| -    }
 | 
| +    /* initialize it; in case of error this deallocates `exec' too */
 | 
| +    error = Init_Context( exec, memory );
 | 
| +    if ( error )
 | 
| +      goto Fail;
 | 
|  
 | 
| -    return driver->context;
 | 
| +    return exec;
 | 
|  
 | 
|    Fail:
 | 
|      return NULL;
 | 
| @@ -834,8 +668,8 @@
 | 
|      /*  SFvTL +   */  PACK( 2, 0 ),
 | 
|      /*  SPvFS     */  PACK( 2, 0 ),
 | 
|      /*  SFvFS     */  PACK( 2, 0 ),
 | 
| -    /*  GPV       */  PACK( 0, 2 ),
 | 
| -    /*  GFV       */  PACK( 0, 2 ),
 | 
| +    /*  GPv       */  PACK( 0, 2 ),
 | 
| +    /*  GFv       */  PACK( 0, 2 ),
 | 
|      /*  SFvTPv    */  PACK( 0, 0 ),
 | 
|      /*  ISECT     */  PACK( 5, 0 ),
 | 
|  
 | 
| @@ -964,8 +798,8 @@
 | 
|      /*  INS_$83   */  PACK( 0, 0 ),
 | 
|      /*  INS_$84   */  PACK( 0, 0 ),
 | 
|      /*  ScanCTRL  */  PACK( 1, 0 ),
 | 
| -    /*  SDPVTL[0] */  PACK( 2, 0 ),
 | 
| -    /*  SDPVTL[1] */  PACK( 2, 0 ),
 | 
| +    /*  SDPvTL[0] */  PACK( 2, 0 ),
 | 
| +    /*  SDPvTL[1] */  PACK( 2, 0 ),
 | 
|      /*  GetINFO   */  PACK( 1, 1 ),
 | 
|      /*  IDEF      */  PACK( 1, 0 ),
 | 
|      /*  ROLL      */  PACK( 3, 3 ),
 | 
| @@ -1098,280 +932,284 @@
 | 
|  
 | 
|  #ifdef FT_DEBUG_LEVEL_TRACE
 | 
|  
 | 
| +  /* the first hex digit gives the length of the opcode name; the space */
 | 
| +  /* after the digit is here just to increase readability of the source */
 | 
| +  /* code                                                               */
 | 
| +
 | 
|    static
 | 
|    const char*  const opcode_name[256] =
 | 
|    {
 | 
| -    "SVTCA y",
 | 
| -    "SVTCA x",
 | 
| -    "SPvTCA y",
 | 
| -    "SPvTCA x",
 | 
| -    "SFvTCA y",
 | 
| -    "SFvTCA x",
 | 
| -    "SPvTL ||",
 | 
| -    "SPvTL +",
 | 
| -    "SFvTL ||",
 | 
| -    "SFvTL +",
 | 
| -    "SPvFS",
 | 
| -    "SFvFS",
 | 
| -    "GPV",
 | 
| -    "GFV",
 | 
| -    "SFvTPv",
 | 
| -    "ISECT",
 | 
| -
 | 
| -    "SRP0",
 | 
| -    "SRP1",
 | 
| -    "SRP2",
 | 
| -    "SZP0",
 | 
| -    "SZP1",
 | 
| -    "SZP2",
 | 
| -    "SZPS",
 | 
| -    "SLOOP",
 | 
| -    "RTG",
 | 
| -    "RTHG",
 | 
| -    "SMD",
 | 
| -    "ELSE",
 | 
| -    "JMPR",
 | 
| -    "SCvTCi",
 | 
| -    "SSwCi",
 | 
| -    "SSW",
 | 
| -
 | 
| -    "DUP",
 | 
| -    "POP",
 | 
| -    "CLEAR",
 | 
| -    "SWAP",
 | 
| -    "DEPTH",
 | 
| -    "CINDEX",
 | 
| -    "MINDEX",
 | 
| -    "AlignPTS",
 | 
| -    "INS_$28",
 | 
| -    "UTP",
 | 
| -    "LOOPCALL",
 | 
| -    "CALL",
 | 
| -    "FDEF",
 | 
| -    "ENDF",
 | 
| -    "MDAP[0]",
 | 
| -    "MDAP[1]",
 | 
| -
 | 
| -    "IUP[0]",
 | 
| -    "IUP[1]",
 | 
| -    "SHP[0]",
 | 
| -    "SHP[1]",
 | 
| -    "SHC[0]",
 | 
| -    "SHC[1]",
 | 
| -    "SHZ[0]",
 | 
| -    "SHZ[1]",
 | 
| -    "SHPIX",
 | 
| -    "IP",
 | 
| -    "MSIRP[0]",
 | 
| -    "MSIRP[1]",
 | 
| -    "AlignRP",
 | 
| -    "RTDG",
 | 
| -    "MIAP[0]",
 | 
| -    "MIAP[1]",
 | 
| -
 | 
| -    "NPushB",
 | 
| -    "NPushW",
 | 
| -    "WS",
 | 
| -    "RS",
 | 
| -    "WCvtP",
 | 
| -    "RCvt",
 | 
| -    "GC[0]",
 | 
| -    "GC[1]",
 | 
| -    "SCFS",
 | 
| -    "MD[0]",
 | 
| -    "MD[1]",
 | 
| -    "MPPEM",
 | 
| -    "MPS",
 | 
| -    "FlipON",
 | 
| -    "FlipOFF",
 | 
| -    "DEBUG",
 | 
| -
 | 
| -    "LT",
 | 
| -    "LTEQ",
 | 
| -    "GT",
 | 
| -    "GTEQ",
 | 
| -    "EQ",
 | 
| -    "NEQ",
 | 
| -    "ODD",
 | 
| -    "EVEN",
 | 
| -    "IF",
 | 
| -    "EIF",
 | 
| -    "AND",
 | 
| -    "OR",
 | 
| -    "NOT",
 | 
| -    "DeltaP1",
 | 
| -    "SDB",
 | 
| -    "SDS",
 | 
| -
 | 
| -    "ADD",
 | 
| -    "SUB",
 | 
| -    "DIV",
 | 
| -    "MUL",
 | 
| -    "ABS",
 | 
| -    "NEG",
 | 
| -    "FLOOR",
 | 
| -    "CEILING",
 | 
| -    "ROUND[0]",
 | 
| -    "ROUND[1]",
 | 
| -    "ROUND[2]",
 | 
| -    "ROUND[3]",
 | 
| -    "NROUND[0]",
 | 
| -    "NROUND[1]",
 | 
| -    "NROUND[2]",
 | 
| -    "NROUND[3]",
 | 
| -
 | 
| -    "WCvtF",
 | 
| -    "DeltaP2",
 | 
| -    "DeltaP3",
 | 
| -    "DeltaCn[0]",
 | 
| -    "DeltaCn[1]",
 | 
| -    "DeltaCn[2]",
 | 
| -    "SROUND",
 | 
| -    "S45Round",
 | 
| -    "JROT",
 | 
| -    "JROF",
 | 
| -    "ROFF",
 | 
| -    "INS_$7B",
 | 
| -    "RUTG",
 | 
| -    "RDTG",
 | 
| -    "SANGW",
 | 
| -    "AA",
 | 
| -
 | 
| -    "FlipPT",
 | 
| -    "FlipRgON",
 | 
| -    "FlipRgOFF",
 | 
| -    "INS_$83",
 | 
| -    "INS_$84",
 | 
| -    "ScanCTRL",
 | 
| -    "SDVPTL[0]",
 | 
| -    "SDVPTL[1]",
 | 
| -    "GetINFO",
 | 
| -    "IDEF",
 | 
| -    "ROLL",
 | 
| -    "MAX",
 | 
| -    "MIN",
 | 
| -    "ScanTYPE",
 | 
| -    "InstCTRL",
 | 
| -    "INS_$8F",
 | 
| -
 | 
| -    "INS_$90",
 | 
| -    "INS_$91",
 | 
| -    "INS_$92",
 | 
| -    "INS_$93",
 | 
| -    "INS_$94",
 | 
| -    "INS_$95",
 | 
| -    "INS_$96",
 | 
| -    "INS_$97",
 | 
| -    "INS_$98",
 | 
| -    "INS_$99",
 | 
| -    "INS_$9A",
 | 
| -    "INS_$9B",
 | 
| -    "INS_$9C",
 | 
| -    "INS_$9D",
 | 
| -    "INS_$9E",
 | 
| -    "INS_$9F",
 | 
| -
 | 
| -    "INS_$A0",
 | 
| -    "INS_$A1",
 | 
| -    "INS_$A2",
 | 
| -    "INS_$A3",
 | 
| -    "INS_$A4",
 | 
| -    "INS_$A5",
 | 
| -    "INS_$A6",
 | 
| -    "INS_$A7",
 | 
| -    "INS_$A8",
 | 
| -    "INS_$A9",
 | 
| -    "INS_$AA",
 | 
| -    "INS_$AB",
 | 
| -    "INS_$AC",
 | 
| -    "INS_$AD",
 | 
| -    "INS_$AE",
 | 
| -    "INS_$AF",
 | 
| -
 | 
| -    "PushB[0]",
 | 
| -    "PushB[1]",
 | 
| -    "PushB[2]",
 | 
| -    "PushB[3]",
 | 
| -    "PushB[4]",
 | 
| -    "PushB[5]",
 | 
| -    "PushB[6]",
 | 
| -    "PushB[7]",
 | 
| -    "PushW[0]",
 | 
| -    "PushW[1]",
 | 
| -    "PushW[2]",
 | 
| -    "PushW[3]",
 | 
| -    "PushW[4]",
 | 
| -    "PushW[5]",
 | 
| -    "PushW[6]",
 | 
| -    "PushW[7]",
 | 
| -
 | 
| -    "MDRP[00]",
 | 
| -    "MDRP[01]",
 | 
| -    "MDRP[02]",
 | 
| -    "MDRP[03]",
 | 
| -    "MDRP[04]",
 | 
| -    "MDRP[05]",
 | 
| -    "MDRP[06]",
 | 
| -    "MDRP[07]",
 | 
| -    "MDRP[08]",
 | 
| -    "MDRP[09]",
 | 
| -    "MDRP[10]",
 | 
| -    "MDRP[11]",
 | 
| -    "MDRP[12]",
 | 
| -    "MDRP[13]",
 | 
| -    "MDRP[14]",
 | 
| -    "MDRP[15]",
 | 
| -
 | 
| -    "MDRP[16]",
 | 
| -    "MDRP[17]",
 | 
| -    "MDRP[18]",
 | 
| -    "MDRP[19]",
 | 
| -    "MDRP[20]",
 | 
| -    "MDRP[21]",
 | 
| -    "MDRP[22]",
 | 
| -    "MDRP[23]",
 | 
| -    "MDRP[24]",
 | 
| -    "MDRP[25]",
 | 
| -    "MDRP[26]",
 | 
| -    "MDRP[27]",
 | 
| -    "MDRP[28]",
 | 
| -    "MDRP[29]",
 | 
| -    "MDRP[30]",
 | 
| -    "MDRP[31]",
 | 
| -
 | 
| -    "MIRP[00]",
 | 
| -    "MIRP[01]",
 | 
| -    "MIRP[02]",
 | 
| -    "MIRP[03]",
 | 
| -    "MIRP[04]",
 | 
| -    "MIRP[05]",
 | 
| -    "MIRP[06]",
 | 
| -    "MIRP[07]",
 | 
| -    "MIRP[08]",
 | 
| -    "MIRP[09]",
 | 
| -    "MIRP[10]",
 | 
| -    "MIRP[11]",
 | 
| -    "MIRP[12]",
 | 
| -    "MIRP[13]",
 | 
| -    "MIRP[14]",
 | 
| -    "MIRP[15]",
 | 
| -
 | 
| -    "MIRP[16]",
 | 
| -    "MIRP[17]",
 | 
| -    "MIRP[18]",
 | 
| -    "MIRP[19]",
 | 
| -    "MIRP[20]",
 | 
| -    "MIRP[21]",
 | 
| -    "MIRP[22]",
 | 
| -    "MIRP[23]",
 | 
| -    "MIRP[24]",
 | 
| -    "MIRP[25]",
 | 
| -    "MIRP[26]",
 | 
| -    "MIRP[27]",
 | 
| -    "MIRP[28]",
 | 
| -    "MIRP[29]",
 | 
| -    "MIRP[30]",
 | 
| -    "MIRP[31]"
 | 
| +    "7 SVTCA y",
 | 
| +    "7 SVTCA x",
 | 
| +    "8 SPvTCA y",
 | 
| +    "8 SPvTCA x",
 | 
| +    "8 SFvTCA y",
 | 
| +    "8 SFvTCA x",
 | 
| +    "8 SPvTL ||",
 | 
| +    "7 SPvTL +",
 | 
| +    "8 SFvTL ||",
 | 
| +    "7 SFvTL +",
 | 
| +    "5 SPvFS",
 | 
| +    "5 SFvFS",
 | 
| +    "3 GPv",
 | 
| +    "3 GFv",
 | 
| +    "6 SFvTPv",
 | 
| +    "5 ISECT",
 | 
| +
 | 
| +    "4 SRP0",
 | 
| +    "4 SRP1",
 | 
| +    "4 SRP2",
 | 
| +    "4 SZP0",
 | 
| +    "4 SZP1",
 | 
| +    "4 SZP2",
 | 
| +    "4 SZPS",
 | 
| +    "5 SLOOP",
 | 
| +    "3 RTG",
 | 
| +    "4 RTHG",
 | 
| +    "3 SMD",
 | 
| +    "4 ELSE",
 | 
| +    "4 JMPR",
 | 
| +    "6 SCvTCi",
 | 
| +    "5 SSwCi",
 | 
| +    "3 SSW",
 | 
| +
 | 
| +    "3 DUP",
 | 
| +    "3 POP",
 | 
| +    "5 CLEAR",
 | 
| +    "4 SWAP",
 | 
| +    "5 DEPTH",
 | 
| +    "6 CINDEX",
 | 
| +    "6 MINDEX",
 | 
| +    "8 AlignPTS",
 | 
| +    "7 INS_$28",
 | 
| +    "3 UTP",
 | 
| +    "8 LOOPCALL",
 | 
| +    "4 CALL",
 | 
| +    "4 FDEF",
 | 
| +    "4 ENDF",
 | 
| +    "7 MDAP[0]",
 | 
| +    "7 MDAP[1]",
 | 
| +
 | 
| +    "6 IUP[0]",
 | 
| +    "6 IUP[1]",
 | 
| +    "6 SHP[0]",
 | 
| +    "6 SHP[1]",
 | 
| +    "6 SHC[0]",
 | 
| +    "6 SHC[1]",
 | 
| +    "6 SHZ[0]",
 | 
| +    "6 SHZ[1]",
 | 
| +    "5 SHPIX",
 | 
| +    "2 IP",
 | 
| +    "8 MSIRP[0]",
 | 
| +    "8 MSIRP[1]",
 | 
| +    "7 AlignRP",
 | 
| +    "4 RTDG",
 | 
| +    "7 MIAP[0]",
 | 
| +    "7 MIAP[1]",
 | 
| +
 | 
| +    "6 NPushB",
 | 
| +    "6 NPushW",
 | 
| +    "2 WS",
 | 
| +    "2 RS",
 | 
| +    "5 WCvtP",
 | 
| +    "4 RCvt",
 | 
| +    "5 GC[0]",
 | 
| +    "5 GC[1]",
 | 
| +    "4 SCFS",
 | 
| +    "5 MD[0]",
 | 
| +    "5 MD[1]",
 | 
| +    "5 MPPEM",
 | 
| +    "3 MPS",
 | 
| +    "6 FlipON",
 | 
| +    "7 FlipOFF",
 | 
| +    "5 DEBUG",
 | 
| +
 | 
| +    "2 LT",
 | 
| +    "4 LTEQ",
 | 
| +    "2 GT",
 | 
| +    "4 GTEQ",
 | 
| +    "2 EQ",
 | 
| +    "3 NEQ",
 | 
| +    "3 ODD",
 | 
| +    "4 EVEN",
 | 
| +    "2 IF",
 | 
| +    "3 EIF",
 | 
| +    "3 AND",
 | 
| +    "2 OR",
 | 
| +    "3 NOT",
 | 
| +    "7 DeltaP1",
 | 
| +    "3 SDB",
 | 
| +    "3 SDS",
 | 
| +
 | 
| +    "3 ADD",
 | 
| +    "3 SUB",
 | 
| +    "3 DIV",
 | 
| +    "3 MUL",
 | 
| +    "3 ABS",
 | 
| +    "3 NEG",
 | 
| +    "5 FLOOR",
 | 
| +    "7 CEILING",
 | 
| +    "8 ROUND[0]",
 | 
| +    "8 ROUND[1]",
 | 
| +    "8 ROUND[2]",
 | 
| +    "8 ROUND[3]",
 | 
| +    "9 NROUND[0]",
 | 
| +    "9 NROUND[1]",
 | 
| +    "9 NROUND[2]",
 | 
| +    "9 NROUND[3]",
 | 
| +
 | 
| +    "5 WCvtF",
 | 
| +    "7 DeltaP2",
 | 
| +    "7 DeltaP3",
 | 
| +    "A DeltaCn[0]",
 | 
| +    "A DeltaCn[1]",
 | 
| +    "A DeltaCn[2]",
 | 
| +    "6 SROUND",
 | 
| +    "8 S45Round",
 | 
| +    "4 JROT",
 | 
| +    "4 JROF",
 | 
| +    "4 ROFF",
 | 
| +    "7 INS_$7B",
 | 
| +    "4 RUTG",
 | 
| +    "4 RDTG",
 | 
| +    "5 SANGW",
 | 
| +    "2 AA",
 | 
| +
 | 
| +    "6 FlipPT",
 | 
| +    "8 FlipRgON",
 | 
| +    "9 FlipRgOFF",
 | 
| +    "7 INS_$83",
 | 
| +    "7 INS_$84",
 | 
| +    "8 ScanCTRL",
 | 
| +    "9 SDPvTL[0]",
 | 
| +    "9 SDPvTL[1]",
 | 
| +    "7 GetINFO",
 | 
| +    "4 IDEF",
 | 
| +    "4 ROLL",
 | 
| +    "3 MAX",
 | 
| +    "3 MIN",
 | 
| +    "8 ScanTYPE",
 | 
| +    "8 InstCTRL",
 | 
| +    "7 INS_$8F",
 | 
| +
 | 
| +    "7 INS_$90",
 | 
| +    "7 INS_$91",
 | 
| +    "7 INS_$92",
 | 
| +    "7 INS_$93",
 | 
| +    "7 INS_$94",
 | 
| +    "7 INS_$95",
 | 
| +    "7 INS_$96",
 | 
| +    "7 INS_$97",
 | 
| +    "7 INS_$98",
 | 
| +    "7 INS_$99",
 | 
| +    "7 INS_$9A",
 | 
| +    "7 INS_$9B",
 | 
| +    "7 INS_$9C",
 | 
| +    "7 INS_$9D",
 | 
| +    "7 INS_$9E",
 | 
| +    "7 INS_$9F",
 | 
| +
 | 
| +    "7 INS_$A0",
 | 
| +    "7 INS_$A1",
 | 
| +    "7 INS_$A2",
 | 
| +    "7 INS_$A3",
 | 
| +    "7 INS_$A4",
 | 
| +    "7 INS_$A5",
 | 
| +    "7 INS_$A6",
 | 
| +    "7 INS_$A7",
 | 
| +    "7 INS_$A8",
 | 
| +    "7 INS_$A9",
 | 
| +    "7 INS_$AA",
 | 
| +    "7 INS_$AB",
 | 
| +    "7 INS_$AC",
 | 
| +    "7 INS_$AD",
 | 
| +    "7 INS_$AE",
 | 
| +    "7 INS_$AF",
 | 
| +
 | 
| +    "8 PushB[0]",
 | 
| +    "8 PushB[1]",
 | 
| +    "8 PushB[2]",
 | 
| +    "8 PushB[3]",
 | 
| +    "8 PushB[4]",
 | 
| +    "8 PushB[5]",
 | 
| +    "8 PushB[6]",
 | 
| +    "8 PushB[7]",
 | 
| +    "8 PushW[0]",
 | 
| +    "8 PushW[1]",
 | 
| +    "8 PushW[2]",
 | 
| +    "8 PushW[3]",
 | 
| +    "8 PushW[4]",
 | 
| +    "8 PushW[5]",
 | 
| +    "8 PushW[6]",
 | 
| +    "8 PushW[7]",
 | 
| +
 | 
| +    "8 MDRP[00]",
 | 
| +    "8 MDRP[01]",
 | 
| +    "8 MDRP[02]",
 | 
| +    "8 MDRP[03]",
 | 
| +    "8 MDRP[04]",
 | 
| +    "8 MDRP[05]",
 | 
| +    "8 MDRP[06]",
 | 
| +    "8 MDRP[07]",
 | 
| +    "8 MDRP[08]",
 | 
| +    "8 MDRP[09]",
 | 
| +    "8 MDRP[10]",
 | 
| +    "8 MDRP[11]",
 | 
| +    "8 MDRP[12]",
 | 
| +    "8 MDRP[13]",
 | 
| +    "8 MDRP[14]",
 | 
| +    "8 MDRP[15]",
 | 
| +
 | 
| +    "8 MDRP[16]",
 | 
| +    "8 MDRP[17]",
 | 
| +    "8 MDRP[18]",
 | 
| +    "8 MDRP[19]",
 | 
| +    "8 MDRP[20]",
 | 
| +    "8 MDRP[21]",
 | 
| +    "8 MDRP[22]",
 | 
| +    "8 MDRP[23]",
 | 
| +    "8 MDRP[24]",
 | 
| +    "8 MDRP[25]",
 | 
| +    "8 MDRP[26]",
 | 
| +    "8 MDRP[27]",
 | 
| +    "8 MDRP[28]",
 | 
| +    "8 MDRP[29]",
 | 
| +    "8 MDRP[30]",
 | 
| +    "8 MDRP[31]",
 | 
| +
 | 
| +    "8 MIRP[00]",
 | 
| +    "8 MIRP[01]",
 | 
| +    "8 MIRP[02]",
 | 
| +    "8 MIRP[03]",
 | 
| +    "8 MIRP[04]",
 | 
| +    "8 MIRP[05]",
 | 
| +    "8 MIRP[06]",
 | 
| +    "8 MIRP[07]",
 | 
| +    "8 MIRP[08]",
 | 
| +    "8 MIRP[09]",
 | 
| +    "8 MIRP[10]",
 | 
| +    "8 MIRP[11]",
 | 
| +    "8 MIRP[12]",
 | 
| +    "8 MIRP[13]",
 | 
| +    "8 MIRP[14]",
 | 
| +    "8 MIRP[15]",
 | 
| +
 | 
| +    "8 MIRP[16]",
 | 
| +    "8 MIRP[17]",
 | 
| +    "8 MIRP[18]",
 | 
| +    "8 MIRP[19]",
 | 
| +    "8 MIRP[20]",
 | 
| +    "8 MIRP[21]",
 | 
| +    "8 MIRP[22]",
 | 
| +    "8 MIRP[23]",
 | 
| +    "8 MIRP[24]",
 | 
| +    "8 MIRP[25]",
 | 
| +    "8 MIRP[26]",
 | 
| +    "8 MIRP[27]",
 | 
| +    "8 MIRP[28]",
 | 
| +    "8 MIRP[29]",
 | 
| +    "8 MIRP[30]",
 | 
| +    "8 MIRP[31]"
 | 
|    };
 | 
|  
 | 
|  #endif /* FT_DEBUG_LEVEL_TRACE */
 | 
| @@ -1637,55 +1475,55 @@
 | 
|    /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
 | 
|    /*                                                                       */
 | 
|    static FT_Long
 | 
| -  Current_Ratio( EXEC_OP )
 | 
| +  Current_Ratio( TT_ExecContext  exc )
 | 
|    {
 | 
| -    if ( !CUR.tt_metrics.ratio )
 | 
| +    if ( !exc->tt_metrics.ratio )
 | 
|      {
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -      if ( CUR.face->unpatented_hinting )
 | 
| +      if ( exc->face->unpatented_hinting )
 | 
|        {
 | 
| -        if ( CUR.GS.both_x_axis )
 | 
| -          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
 | 
| +        if ( exc->GS.both_x_axis )
 | 
| +          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
 | 
|          else
 | 
| -          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
 | 
| +          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
 | 
|        }
 | 
|        else
 | 
|  #endif
 | 
|        {
 | 
| -        if ( CUR.GS.projVector.y == 0 )
 | 
| -          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
 | 
| +        if ( exc->GS.projVector.y == 0 )
 | 
| +          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
 | 
|  
 | 
| -        else if ( CUR.GS.projVector.x == 0 )
 | 
| -          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
 | 
| +        else if ( exc->GS.projVector.x == 0 )
 | 
| +          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
 | 
|  
 | 
|          else
 | 
|          {
 | 
|            FT_F26Dot6  x, y;
 | 
|  
 | 
|  
 | 
| -          x = TT_MulFix14( CUR.tt_metrics.x_ratio,
 | 
| -                           CUR.GS.projVector.x );
 | 
| -          y = TT_MulFix14( CUR.tt_metrics.y_ratio,
 | 
| -                           CUR.GS.projVector.y );
 | 
| -          CUR.tt_metrics.ratio = FT_Hypot( x, y );
 | 
| +          x = TT_MulFix14( exc->tt_metrics.x_ratio,
 | 
| +                           exc->GS.projVector.x );
 | 
| +          y = TT_MulFix14( exc->tt_metrics.y_ratio,
 | 
| +                           exc->GS.projVector.y );
 | 
| +          exc->tt_metrics.ratio = FT_Hypot( x, y );
 | 
|          }
 | 
|        }
 | 
|      }
 | 
| -    return CUR.tt_metrics.ratio;
 | 
| +    return exc->tt_metrics.ratio;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( FT_Long )
 | 
| -  Current_Ppem( EXEC_OP )
 | 
| +  Current_Ppem( TT_ExecContext  exc )
 | 
|    {
 | 
| -    return CUR.tt_metrics.ppem;
 | 
| +    return exc->tt_metrics.ppem;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( FT_Long )
 | 
| -  Current_Ppem_Stretched( EXEC_OP )
 | 
| +  Current_Ppem_Stretched( TT_ExecContext  exc )
 | 
|    {
 | 
| -    return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
 | 
| +    return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -1697,48 +1535,54 @@
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( FT_F26Dot6 )
 | 
| -  Read_CVT( EXEC_OP_ FT_ULong  idx )
 | 
| +  Read_CVT( TT_ExecContext  exc,
 | 
| +            FT_ULong        idx )
 | 
|    {
 | 
| -    return CUR.cvt[idx];
 | 
| +    return exc->cvt[idx];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( FT_F26Dot6 )
 | 
| -  Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )
 | 
| +  Read_CVT_Stretched( TT_ExecContext  exc,
 | 
| +                      FT_ULong        idx )
 | 
|    {
 | 
| -    return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
 | 
| +    return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( void )
 | 
| -  Write_CVT( EXEC_OP_ FT_ULong    idx,
 | 
| -                      FT_F26Dot6  value )
 | 
| +  Write_CVT( TT_ExecContext  exc,
 | 
| +             FT_ULong        idx,
 | 
| +             FT_F26Dot6      value )
 | 
|    {
 | 
| -    CUR.cvt[idx] = value;
 | 
| +    exc->cvt[idx] = value;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( void )
 | 
| -  Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
 | 
| -                                FT_F26Dot6  value )
 | 
| +  Write_CVT_Stretched( TT_ExecContext  exc,
 | 
| +                       FT_ULong        idx,
 | 
| +                       FT_F26Dot6      value )
 | 
|    {
 | 
| -    CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
 | 
| +    exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( void )
 | 
| -  Move_CVT( EXEC_OP_ FT_ULong    idx,
 | 
| -                     FT_F26Dot6  value )
 | 
| +  Move_CVT( TT_ExecContext  exc,
 | 
| +            FT_ULong        idx,
 | 
| +            FT_F26Dot6      value )
 | 
|    {
 | 
| -    CUR.cvt[idx] += value;
 | 
| +    exc->cvt[idx] += value;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    FT_CALLBACK_DEF( void )
 | 
| -  Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
 | 
| -                               FT_F26Dot6  value )
 | 
| +  Move_CVT_Stretched( TT_ExecContext  exc,
 | 
| +                      FT_ULong        idx,
 | 
| +                      FT_F26Dot6      value )
 | 
|    {
 | 
| -    CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
 | 
| +    exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -1758,12 +1602,12 @@
 | 
|    /*    This one could become a macro.                                     */
 | 
|    /*                                                                       */
 | 
|    static FT_Short
 | 
| -  GetShortIns( EXEC_OP )
 | 
| +  GetShortIns( TT_ExecContext  exc )
 | 
|    {
 | 
|      /* Reading a byte stream so there is no endianess (DaveP) */
 | 
| -    CUR.IP += 2;
 | 
| -    return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
 | 
| -                         CUR.code[CUR.IP - 1]      );
 | 
| +    exc->IP += 2;
 | 
| +    return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
 | 
| +                         exc->code[exc->IP - 1]      );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -1784,23 +1628,24 @@
 | 
|    /*    SUCCESS or FAILURE.                                                */
 | 
|    /*                                                                       */
 | 
|    static FT_Bool
 | 
| -  Ins_Goto_CodeRange( EXEC_OP_ FT_Int    aRange,
 | 
| -                               FT_ULong  aIP )
 | 
| +  Ins_Goto_CodeRange( TT_ExecContext  exc,
 | 
| +                      FT_Int          aRange,
 | 
| +                      FT_Long         aIP )
 | 
|    {
 | 
|      TT_CodeRange*  range;
 | 
|  
 | 
|  
 | 
|      if ( aRange < 1 || aRange > 3 )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Bad_Argument );
 | 
| +      exc->error = FT_THROW( Bad_Argument );
 | 
|        return FAILURE;
 | 
|      }
 | 
|  
 | 
| -    range = &CUR.codeRangeTable[aRange - 1];
 | 
| +    range = &exc->codeRangeTable[aRange - 1];
 | 
|  
 | 
|      if ( range->base == NULL )     /* invalid coderange */
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Invalid_CodeRange );
 | 
| +      exc->error = FT_THROW( Invalid_CodeRange );
 | 
|        return FAILURE;
 | 
|      }
 | 
|  
 | 
| @@ -1810,14 +1655,14 @@
 | 
|  
 | 
|      if ( aIP > range->size )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Code_Overflow );
 | 
| +      exc->error = FT_THROW( Code_Overflow );
 | 
|        return FAILURE;
 | 
|      }
 | 
|  
 | 
| -    CUR.code     = range->base;
 | 
| -    CUR.codeSize = range->size;
 | 
| -    CUR.IP       = aIP;
 | 
| -    CUR.curRange = aRange;
 | 
| +    exc->code     = range->base;
 | 
| +    exc->codeSize = range->size;
 | 
| +    exc->IP       = aIP;
 | 
| +    exc->curRange = aRange;
 | 
|  
 | 
|      return SUCCESS;
 | 
|    }
 | 
| @@ -1841,36 +1686,37 @@
 | 
|    /*    zone     :: The affected glyph zone.                               */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Direct_Move( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                        FT_UShort     point,
 | 
| -                        FT_F26Dot6    distance )
 | 
| +  Direct_Move( TT_ExecContext  exc,
 | 
| +               TT_GlyphZone    zone,
 | 
| +               FT_UShort       point,
 | 
| +               FT_F26Dot6      distance )
 | 
|    {
 | 
|      FT_F26Dot6  v;
 | 
|  
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    FT_ASSERT( !CUR.face->unpatented_hinting );
 | 
| +    FT_ASSERT( !exc->face->unpatented_hinting );
 | 
|  #endif
 | 
|  
 | 
| -    v = CUR.GS.freeVector.x;
 | 
| +    v = exc->GS.freeVector.x;
 | 
|  
 | 
|      if ( v != 0 )
 | 
|      {
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -      if ( !SUBPIXEL_HINTING                                     ||
 | 
| -           ( !CUR.ignore_x_mode                                ||
 | 
| -             ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
 | 
| +      if ( !SUBPIXEL_HINTING                                      ||
 | 
| +           ( !exc->ignore_x_mode                                ||
 | 
| +             ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| -        zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
 | 
| +        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 | 
|  
 | 
|        zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
 | 
|      }
 | 
|  
 | 
| -    v = CUR.GS.freeVector.y;
 | 
| +    v = exc->GS.freeVector.y;
 | 
|  
 | 
|      if ( v != 0 )
 | 
|      {
 | 
| -      zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
 | 
| +      zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
 | 
|  
 | 
|        zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
 | 
|      }
 | 
| @@ -1895,26 +1741,27 @@
 | 
|    /*    zone     :: The affected glyph zone.                               */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Direct_Move_Orig( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                             FT_UShort     point,
 | 
| -                             FT_F26Dot6    distance )
 | 
| +  Direct_Move_Orig( TT_ExecContext  exc,
 | 
| +                    TT_GlyphZone    zone,
 | 
| +                    FT_UShort       point,
 | 
| +                    FT_F26Dot6      distance )
 | 
|    {
 | 
|      FT_F26Dot6  v;
 | 
|  
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    FT_ASSERT( !CUR.face->unpatented_hinting );
 | 
| +    FT_ASSERT( !exc->face->unpatented_hinting );
 | 
|  #endif
 | 
|  
 | 
| -    v = CUR.GS.freeVector.x;
 | 
| +    v = exc->GS.freeVector.x;
 | 
|  
 | 
|      if ( v != 0 )
 | 
| -      zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
 | 
| +      zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 | 
|  
 | 
| -    v = CUR.GS.freeVector.y;
 | 
| +    v = exc->GS.freeVector.y;
 | 
|  
 | 
|      if ( v != 0 )
 | 
| -      zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
 | 
| +      zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -1929,15 +1776,16 @@
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Direct_Move_X( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                          FT_UShort     point,
 | 
| -                          FT_F26Dot6    distance )
 | 
| +  Direct_Move_X( TT_ExecContext  exc,
 | 
| +                 TT_GlyphZone    zone,
 | 
| +                 FT_UShort       point,
 | 
| +                 FT_F26Dot6      distance )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( !SUBPIXEL_HINTING  ||
 | 
| -         !CUR.ignore_x_mode )
 | 
| +    if ( !SUBPIXEL_HINTING   ||
 | 
| +         !exc->ignore_x_mode )
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|        zone->cur[point].x += distance;
 | 
|  
 | 
| @@ -1946,11 +1794,12 @@
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Direct_Move_Y( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                          FT_UShort     point,
 | 
| -                          FT_F26Dot6    distance )
 | 
| +  Direct_Move_Y( TT_ExecContext  exc,
 | 
| +                 TT_GlyphZone    zone,
 | 
| +                 FT_UShort       point,
 | 
| +                 FT_F26Dot6      distance )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|      zone->cur[point].y += distance;
 | 
|      zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
 | 
| @@ -1968,22 +1817,24 @@
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                               FT_UShort     point,
 | 
| -                               FT_F26Dot6    distance )
 | 
| +  Direct_Move_Orig_X( TT_ExecContext  exc,
 | 
| +                      TT_GlyphZone    zone,
 | 
| +                      FT_UShort       point,
 | 
| +                      FT_F26Dot6      distance )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|      zone->org[point].x += distance;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone  zone,
 | 
| -                               FT_UShort     point,
 | 
| -                               FT_F26Dot6    distance )
 | 
| +  Direct_Move_Orig_Y( TT_ExecContext  exc,
 | 
| +                      TT_GlyphZone    zone,
 | 
| +                      FT_UShort       point,
 | 
| +                      FT_F26Dot6      distance )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|      zone->org[point].y += distance;
 | 
|    }
 | 
| @@ -2012,12 +1863,13 @@
 | 
|    /*    before rounding.                                                   */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_None( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                       FT_F26Dot6  compensation )
 | 
| +  Round_None( TT_ExecContext  exc,
 | 
| +              FT_F26Dot6      distance,
 | 
| +              FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2053,12 +1905,13 @@
 | 
|    /*    Rounded distance.                                                  */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                          FT_F26Dot6  compensation )
 | 
| +  Round_To_Grid( TT_ExecContext  exc,
 | 
| +                 FT_F26Dot6      distance,
 | 
| +                 FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2074,7 +1927,7 @@
 | 
|          val = 0;
 | 
|      }
 | 
|  
 | 
| -    return  val;
 | 
| +    return val;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -2095,12 +1948,13 @@
 | 
|    /*    Rounded distance.                                                  */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                               FT_F26Dot6  compensation )
 | 
| +  Round_To_Half_Grid( TT_ExecContext  exc,
 | 
| +                      FT_F26Dot6      distance,
 | 
| +                      FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2137,12 +1991,13 @@
 | 
|    /*    Rounded distance.                                                  */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                               FT_F26Dot6  compensation )
 | 
| +  Round_Down_To_Grid( TT_ExecContext  exc,
 | 
| +                      FT_F26Dot6      distance,
 | 
| +                      FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2179,12 +2034,13 @@
 | 
|    /*    Rounded distance.                                                  */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                             FT_F26Dot6  compensation )
 | 
| +  Round_Up_To_Grid( TT_ExecContext  exc,
 | 
| +                    FT_F26Dot6      distance,
 | 
| +                    FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2221,12 +2077,13 @@
 | 
|    /*    Rounded distance.                                                  */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                                 FT_F26Dot6  compensation )
 | 
| +  Round_To_Double_Grid( TT_ExecContext  exc,
 | 
| +                        FT_F26Dot6      distance,
 | 
| +                        FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6 val;
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
| @@ -2269,27 +2126,28 @@
 | 
|    /*    before rounding.                                                   */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_Super( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                        FT_F26Dot6  compensation )
 | 
| +  Round_Super( TT_ExecContext  exc,
 | 
| +               FT_F26Dot6      distance,
 | 
| +               FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
|      {
 | 
| -      val = ( distance - CUR.phase + CUR.threshold + compensation ) &
 | 
| -              -CUR.period;
 | 
| -      val += CUR.phase;
 | 
| +      val = ( distance - exc->phase + exc->threshold + compensation ) &
 | 
| +              -exc->period;
 | 
| +      val += exc->phase;
 | 
|        if ( val < 0 )
 | 
| -        val = CUR.phase;
 | 
| +        val = exc->phase;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
 | 
| -               -CUR.period );
 | 
| -      val -= CUR.phase;
 | 
| +      val = -( ( exc->threshold - exc->phase - distance + compensation ) &
 | 
| +               -exc->period );
 | 
| +      val -= exc->phase;
 | 
|        if ( val > 0 )
 | 
| -        val = -CUR.phase;
 | 
| +        val = -exc->phase;
 | 
|      }
 | 
|  
 | 
|      return val;
 | 
| @@ -2317,27 +2175,28 @@
 | 
|    /*    greater precision.                                                 */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Round_Super_45( EXEC_OP_ FT_F26Dot6  distance,
 | 
| -                           FT_F26Dot6  compensation )
 | 
| +  Round_Super_45( TT_ExecContext  exc,
 | 
| +                  FT_F26Dot6      distance,
 | 
| +                  FT_F26Dot6      compensation )
 | 
|    {
 | 
|      FT_F26Dot6  val;
 | 
|  
 | 
|  
 | 
|      if ( distance >= 0 )
 | 
|      {
 | 
| -      val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
 | 
| -                CUR.period ) * CUR.period;
 | 
| -      val += CUR.phase;
 | 
| +      val = ( ( distance - exc->phase + exc->threshold + compensation ) /
 | 
| +                exc->period ) * exc->period;
 | 
| +      val += exc->phase;
 | 
|        if ( val < 0 )
 | 
| -        val = CUR.phase;
 | 
| +        val = exc->phase;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
 | 
| -                   CUR.period ) * CUR.period );
 | 
| -      val -= CUR.phase;
 | 
| +      val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
 | 
| +                   exc->period ) * exc->period );
 | 
| +      val -= exc->phase;
 | 
|        if ( val > 0 )
 | 
| -        val = -CUR.phase;
 | 
| +        val = -exc->phase;
 | 
|      }
 | 
|  
 | 
|      return val;
 | 
| @@ -2356,40 +2215,41 @@
 | 
|    /*    round_mode :: The rounding mode to be used.                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Compute_Round( EXEC_OP_ FT_Byte  round_mode )
 | 
| +  Compute_Round( TT_ExecContext  exc,
 | 
| +                 FT_Byte         round_mode )
 | 
|    {
 | 
|      switch ( round_mode )
 | 
|      {
 | 
|      case TT_Round_Off:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_None;
 | 
| +      exc->func_round = (TT_Round_Func)Round_None;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_To_Grid:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_To_Grid;
 | 
| +      exc->func_round = (TT_Round_Func)Round_To_Grid;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_Up_To_Grid:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
 | 
| +      exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_Down_To_Grid:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
 | 
| +      exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_To_Half_Grid:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
 | 
| +      exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_To_Double_Grid:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
 | 
| +      exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_Super:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_Super;
 | 
| +      exc->func_round = (TT_Round_Func)Round_Super;
 | 
|        break;
 | 
|  
 | 
|      case TT_Round_Super_45:
 | 
| -      CUR.func_round = (TT_Round_Func)Round_Super_45;
 | 
| +      exc->func_round = (TT_Round_Func)Round_Super_45;
 | 
|        break;
 | 
|      }
 | 
|    }
 | 
| @@ -2409,57 +2269,58 @@
 | 
|    /*    selector   :: The SROUND opcode.                                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  SetSuperRound( EXEC_OP_ FT_F26Dot6  GridPeriod,
 | 
| -                          FT_Long     selector )
 | 
| +  SetSuperRound( TT_ExecContext  exc,
 | 
| +                 FT_F2Dot14      GridPeriod,
 | 
| +                 FT_Long         selector )
 | 
|    {
 | 
|      switch ( (FT_Int)( selector & 0xC0 ) )
 | 
|      {
 | 
|        case 0:
 | 
| -        CUR.period = GridPeriod / 2;
 | 
| +        exc->period = GridPeriod / 2;
 | 
|          break;
 | 
|  
 | 
|        case 0x40:
 | 
| -        CUR.period = GridPeriod;
 | 
| +        exc->period = GridPeriod;
 | 
|          break;
 | 
|  
 | 
|        case 0x80:
 | 
| -        CUR.period = GridPeriod * 2;
 | 
| +        exc->period = GridPeriod * 2;
 | 
|          break;
 | 
|  
 | 
|        /* This opcode is reserved, but... */
 | 
| -
 | 
|        case 0xC0:
 | 
| -        CUR.period = GridPeriod;
 | 
| +        exc->period = GridPeriod;
 | 
|          break;
 | 
|      }
 | 
|  
 | 
|      switch ( (FT_Int)( selector & 0x30 ) )
 | 
|      {
 | 
|      case 0:
 | 
| -      CUR.phase = 0;
 | 
| +      exc->phase = 0;
 | 
|        break;
 | 
|  
 | 
|      case 0x10:
 | 
| -      CUR.phase = CUR.period / 4;
 | 
| +      exc->phase = exc->period / 4;
 | 
|        break;
 | 
|  
 | 
|      case 0x20:
 | 
| -      CUR.phase = CUR.period / 2;
 | 
| +      exc->phase = exc->period / 2;
 | 
|        break;
 | 
|  
 | 
|      case 0x30:
 | 
| -      CUR.phase = CUR.period * 3 / 4;
 | 
| +      exc->phase = exc->period * 3 / 4;
 | 
|        break;
 | 
|      }
 | 
|  
 | 
|      if ( ( selector & 0x0F ) == 0 )
 | 
| -      CUR.threshold = CUR.period - 1;
 | 
| +      exc->threshold = exc->period - 1;
 | 
|      else
 | 
| -      CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
 | 
| +      exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
 | 
|  
 | 
| -    CUR.period    /= 256;
 | 
| -    CUR.phase     /= 256;
 | 
| -    CUR.threshold /= 256;
 | 
| +    /* convert to F26Dot6 format */
 | 
| +    exc->period    >>= 8;
 | 
| +    exc->phase     >>= 8;
 | 
| +    exc->threshold >>= 8;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -2480,16 +2341,17 @@
 | 
|    /*    The distance in F26dot6 format.                                    */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Project( EXEC_OP_ FT_Pos  dx,
 | 
| -                    FT_Pos  dy )
 | 
| +  Project( TT_ExecContext  exc,
 | 
| +           FT_Pos          dx,
 | 
| +           FT_Pos          dy )
 | 
|    {
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    FT_ASSERT( !CUR.face->unpatented_hinting );
 | 
| +    FT_ASSERT( !exc->face->unpatented_hinting );
 | 
|  #endif
 | 
|  
 | 
| -    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
 | 
| -                        CUR.GS.projVector.x,
 | 
| -                        CUR.GS.projVector.y );
 | 
| +    return TT_DotFix14( dx, dy,
 | 
| +                        exc->GS.projVector.x,
 | 
| +                        exc->GS.projVector.y );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -2510,12 +2372,13 @@
 | 
|    /*    The distance in F26dot6 format.                                    */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Dual_Project( EXEC_OP_ FT_Pos  dx,
 | 
| -                         FT_Pos  dy )
 | 
| +  Dual_Project( TT_ExecContext  exc,
 | 
| +                FT_Pos          dx,
 | 
| +                FT_Pos          dy )
 | 
|    {
 | 
| -    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
 | 
| -                        CUR.GS.dualVector.x,
 | 
| -                        CUR.GS.dualVector.y );
 | 
| +    return TT_DotFix14( dx, dy,
 | 
| +                        exc->GS.dualVector.x,
 | 
| +                        exc->GS.dualVector.y );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -2536,10 +2399,11 @@
 | 
|    /*    The distance in F26dot6 format.                                    */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Project_x( EXEC_OP_ FT_Pos  dx,
 | 
| -                      FT_Pos  dy )
 | 
| +  Project_x( TT_ExecContext  exc,
 | 
| +             FT_Pos          dx,
 | 
| +             FT_Pos          dy )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|      FT_UNUSED( dy );
 | 
|  
 | 
|      return dx;
 | 
| @@ -2563,10 +2427,11 @@
 | 
|    /*    The distance in F26dot6 format.                                    */
 | 
|    /*                                                                       */
 | 
|    static FT_F26Dot6
 | 
| -  Project_y( EXEC_OP_ FT_Pos  dx,
 | 
| -                      FT_Pos  dy )
 | 
| +  Project_y( TT_ExecContext  exc,
 | 
| +             FT_Pos          dx,
 | 
| +             FT_Pos          dy )
 | 
|    {
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_UNUSED( exc );
 | 
|      FT_UNUSED( dx );
 | 
|  
 | 
|      return dy;
 | 
| @@ -2583,101 +2448,101 @@
 | 
|    /*    to the current graphics state.                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Compute_Funcs( EXEC_OP )
 | 
| +  Compute_Funcs( TT_ExecContext  exc )
 | 
|    {
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      /* If both vectors point rightwards along the x axis, set             */
 | 
| -      /* `both-x-axis' true, otherwise set it false.  The x values only     */
 | 
| -      /* need be tested because the vector has been normalised to a unit    */
 | 
| -      /* vector of length 0x4000 = unity.                                   */
 | 
| -      CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
 | 
| -                                      CUR.GS.freeVector.x == 0x4000 );
 | 
| +      /* If both vectors point rightwards along the x axis, set          */
 | 
| +      /* `both-x-axis' true, otherwise set it false.  The x values only  */
 | 
| +      /* need be tested because the vector has been normalised to a unit */
 | 
| +      /* vector of length 0x4000 = unity.                                */
 | 
| +      exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
 | 
| +                                       exc->GS.freeVector.x == 0x4000 );
 | 
|  
 | 
|        /* Throw away projection and freedom vector information */
 | 
|        /* because the patents don't allow them to be stored.   */
 | 
|        /* The relevant US Patents are 5155805 and 5325479.     */
 | 
| -      CUR.GS.projVector.x = 0;
 | 
| -      CUR.GS.projVector.y = 0;
 | 
| -      CUR.GS.freeVector.x = 0;
 | 
| -      CUR.GS.freeVector.y = 0;
 | 
| +      exc->GS.projVector.x = 0;
 | 
| +      exc->GS.projVector.y = 0;
 | 
| +      exc->GS.freeVector.x = 0;
 | 
| +      exc->GS.freeVector.y = 0;
 | 
|  
 | 
| -      if ( CUR.GS.both_x_axis )
 | 
| +      if ( exc->GS.both_x_axis )
 | 
|        {
 | 
| -        CUR.func_project   = Project_x;
 | 
| -        CUR.func_move      = Direct_Move_X;
 | 
| -        CUR.func_move_orig = Direct_Move_Orig_X;
 | 
| +        exc->func_project   = Project_x;
 | 
| +        exc->func_move      = Direct_Move_X;
 | 
| +        exc->func_move_orig = Direct_Move_Orig_X;
 | 
|        }
 | 
|        else
 | 
|        {
 | 
| -        CUR.func_project   = Project_y;
 | 
| -        CUR.func_move      = Direct_Move_Y;
 | 
| -        CUR.func_move_orig = Direct_Move_Orig_Y;
 | 
| +        exc->func_project   = Project_y;
 | 
| +        exc->func_move      = Direct_Move_Y;
 | 
| +        exc->func_move_orig = Direct_Move_Orig_Y;
 | 
|        }
 | 
|  
 | 
| -      if ( CUR.GS.dualVector.x == 0x4000 )
 | 
| -        CUR.func_dualproj = Project_x;
 | 
| -      else if ( CUR.GS.dualVector.y == 0x4000 )
 | 
| -        CUR.func_dualproj = Project_y;
 | 
| +      if ( exc->GS.dualVector.x == 0x4000 )
 | 
| +        exc->func_dualproj = Project_x;
 | 
| +      else if ( exc->GS.dualVector.y == 0x4000 )
 | 
| +        exc->func_dualproj = Project_y;
 | 
|        else
 | 
| -        CUR.func_dualproj = Dual_Project;
 | 
| +        exc->func_dualproj = Dual_Project;
 | 
|  
 | 
|        /* Force recalculation of cached aspect ratio */
 | 
| -      CUR.tt_metrics.ratio = 0;
 | 
| +      exc->tt_metrics.ratio = 0;
 | 
|  
 | 
|        return;
 | 
|      }
 | 
|  #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
 | 
|  
 | 
| -    if ( CUR.GS.freeVector.x == 0x4000 )
 | 
| -      CUR.F_dot_P = CUR.GS.projVector.x;
 | 
| -    else if ( CUR.GS.freeVector.y == 0x4000 )
 | 
| -      CUR.F_dot_P = CUR.GS.projVector.y;
 | 
| +    if ( exc->GS.freeVector.x == 0x4000 )
 | 
| +      exc->F_dot_P = exc->GS.projVector.x;
 | 
| +    else if ( exc->GS.freeVector.y == 0x4000 )
 | 
| +      exc->F_dot_P = exc->GS.projVector.y;
 | 
|      else
 | 
| -      CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
 | 
| -                      (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
 | 
| -                    14;
 | 
| -
 | 
| -    if ( CUR.GS.projVector.x == 0x4000 )
 | 
| -      CUR.func_project = (TT_Project_Func)Project_x;
 | 
| -    else if ( CUR.GS.projVector.y == 0x4000 )
 | 
| -      CUR.func_project = (TT_Project_Func)Project_y;
 | 
| +      exc->F_dot_P =
 | 
| +        ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
 | 
| +          (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
 | 
| +
 | 
| +    if ( exc->GS.projVector.x == 0x4000 )
 | 
| +      exc->func_project = (TT_Project_Func)Project_x;
 | 
| +    else if ( exc->GS.projVector.y == 0x4000 )
 | 
| +      exc->func_project = (TT_Project_Func)Project_y;
 | 
|      else
 | 
| -      CUR.func_project = (TT_Project_Func)Project;
 | 
| +      exc->func_project = (TT_Project_Func)Project;
 | 
|  
 | 
| -    if ( CUR.GS.dualVector.x == 0x4000 )
 | 
| -      CUR.func_dualproj = (TT_Project_Func)Project_x;
 | 
| -    else if ( CUR.GS.dualVector.y == 0x4000 )
 | 
| -      CUR.func_dualproj = (TT_Project_Func)Project_y;
 | 
| +    if ( exc->GS.dualVector.x == 0x4000 )
 | 
| +      exc->func_dualproj = (TT_Project_Func)Project_x;
 | 
| +    else if ( exc->GS.dualVector.y == 0x4000 )
 | 
| +      exc->func_dualproj = (TT_Project_Func)Project_y;
 | 
|      else
 | 
| -      CUR.func_dualproj = (TT_Project_Func)Dual_Project;
 | 
| +      exc->func_dualproj = (TT_Project_Func)Dual_Project;
 | 
|  
 | 
| -    CUR.func_move      = (TT_Move_Func)Direct_Move;
 | 
| -    CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
 | 
| +    exc->func_move      = (TT_Move_Func)Direct_Move;
 | 
| +    exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
 | 
|  
 | 
| -    if ( CUR.F_dot_P == 0x4000L )
 | 
| +    if ( exc->F_dot_P == 0x4000L )
 | 
|      {
 | 
| -      if ( CUR.GS.freeVector.x == 0x4000 )
 | 
| +      if ( exc->GS.freeVector.x == 0x4000 )
 | 
|        {
 | 
| -        CUR.func_move      = (TT_Move_Func)Direct_Move_X;
 | 
| -        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
 | 
| +        exc->func_move      = (TT_Move_Func)Direct_Move_X;
 | 
| +        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
 | 
|        }
 | 
| -      else if ( CUR.GS.freeVector.y == 0x4000 )
 | 
| +      else if ( exc->GS.freeVector.y == 0x4000 )
 | 
|        {
 | 
| -        CUR.func_move      = (TT_Move_Func)Direct_Move_Y;
 | 
| -        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
 | 
| +        exc->func_move      = (TT_Move_Func)Direct_Move_Y;
 | 
| +        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
 | 
|        }
 | 
|      }
 | 
|  
 | 
|      /* at small sizes, F_dot_P can become too small, resulting   */
 | 
|      /* in overflows and `spikes' in a number of glyphs like `w'. */
 | 
|  
 | 
| -    if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
 | 
| -      CUR.F_dot_P = 0x4000L;
 | 
| +    if ( FT_ABS( exc->F_dot_P ) < 0x400L )
 | 
| +      exc->F_dot_P = 0x4000L;
 | 
|  
 | 
|      /* Disable cached aspect ratio */
 | 
| -    CUR.tt_metrics.ratio = 0;
 | 
| +    exc->tt_metrics.ratio = 0;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -2700,36 +2565,31 @@
 | 
|    /*    Returns FAILURE if a vector parameter is zero.                     */
 | 
|    /*                                                                       */
 | 
|    /* <Note>                                                                */
 | 
| -  /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */
 | 
| +  /*    In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and  */
 | 
|    /*    R is undefined.                                                    */
 | 
|    /*                                                                       */
 | 
|    static FT_Bool
 | 
| -  Normalize( EXEC_OP_ FT_F26Dot6      Vx,
 | 
| -                      FT_F26Dot6      Vy,
 | 
| -                      FT_UnitVector*  R )
 | 
| +  Normalize( FT_F26Dot6      Vx,
 | 
| +             FT_F26Dot6      Vy,
 | 
| +             FT_UnitVector*  R )
 | 
|    {
 | 
| -    FT_F26Dot6  W;
 | 
| -
 | 
| -    FT_UNUSED_EXEC;
 | 
| +    FT_Vector V;
 | 
|  
 | 
|  
 | 
| -    if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L )
 | 
| +    if ( Vx == 0 && Vy == 0 )
 | 
|      {
 | 
| -      if ( Vx == 0 && Vy == 0 )
 | 
| -      {
 | 
| -        /* XXX: UNDOCUMENTED! It seems that it is possible to try   */
 | 
| -        /*      to normalize the vector (0,0).  Return immediately. */
 | 
| -        return SUCCESS;
 | 
| -      }
 | 
| -
 | 
| -      Vx *= 0x4000;
 | 
| -      Vy *= 0x4000;
 | 
| +      /* XXX: UNDOCUMENTED! It seems that it is possible to try   */
 | 
| +      /*      to normalize the vector (0,0).  Return immediately. */
 | 
| +      return SUCCESS;
 | 
|      }
 | 
|  
 | 
| -    W = FT_Hypot( Vx, Vy );
 | 
| +    V.x = Vx;
 | 
| +    V.y = Vy;
 | 
|  
 | 
| -    R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
 | 
| -    R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
 | 
| +    FT_Vector_NormLen( &V );
 | 
| +
 | 
| +    R->x = (FT_F2Dot14)( V.x / 4 );
 | 
| +    R->y = (FT_F2Dot14)( V.y / 4 );
 | 
|  
 | 
|      return SUCCESS;
 | 
|    }
 | 
| @@ -2742,2521 +2602,2168 @@
 | 
|    /*************************************************************************/
 | 
|  
 | 
|  
 | 
| -  static FT_Bool
 | 
| -  Ins_SxVTL( EXEC_OP_ FT_UShort       aIdx1,
 | 
| -                      FT_UShort       aIdx2,
 | 
| -                      FT_Int          aOpc,
 | 
| -                      FT_UnitVector*  Vec )
 | 
| -  {
 | 
| -    FT_Long     A, B, C;
 | 
| -    FT_Vector*  p1;
 | 
| -    FT_Vector*  p2;
 | 
| -
 | 
| +#define ARRAY_BOUND_ERROR                         \
 | 
| +    do                                            \
 | 
| +    {                                             \
 | 
| +      exc->error = FT_THROW( Invalid_Reference ); \
 | 
| +      return;                                     \
 | 
| +    } while (0)
 | 
|  
 | 
| -    if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
 | 
| -         BOUNDS( aIdx2, CUR.zp1.n_points ) )
 | 
| -    {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| -      return FAILURE;
 | 
| -    }
 | 
|  
 | 
| -    p1 = CUR.zp1.cur + aIdx2;
 | 
| -    p2 = CUR.zp2.cur + aIdx1;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* MPPEM[]:      Measure Pixel Per EM                                    */
 | 
| +  /* Opcode range: 0x4B                                                    */
 | 
| +  /* Stack:        --> Euint16                                             */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_MPPEM( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    args[0] = exc->func_cur_ppem( exc );
 | 
| +  }
 | 
|  
 | 
| -    A = p1->x - p2->x;
 | 
| -    B = p1->y - p2->y;
 | 
|  
 | 
| -    /* If p1 == p2, SPVTL and SFVTL behave the same as */
 | 
| -    /* SPVTCA[X] and SFVTCA[X], respectively.          */
 | 
| -    /*                                                 */
 | 
| -    /* Confirmed by Greg Hitchcock.                    */
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* MPS[]:        Measure Point Size                                      */
 | 
| +  /* Opcode range: 0x4C                                                    */
 | 
| +  /* Stack:        --> Euint16                                             */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_MPS( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +    /* Note: The point size should be irrelevant in a given font program; */
 | 
| +    /*       we thus decide to return only the PPEM value.                */
 | 
| +#if 0
 | 
| +    args[0] = exc->metrics.pointSize;
 | 
| +#else
 | 
| +    args[0] = exc->func_cur_ppem( exc );
 | 
| +#endif
 | 
| +  }
 | 
|  
 | 
| -    if ( A == 0 && B == 0 )
 | 
| -    {
 | 
| -      A    = 0x4000;
 | 
| -      aOpc = 0;
 | 
| -    }
 | 
|  
 | 
| -    if ( ( aOpc & 1 ) != 0 )
 | 
| -    {
 | 
| -      C =  B;   /* counter clockwise rotation */
 | 
| -      B =  A;
 | 
| -      A = -C;
 | 
| -    }
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* DUP[]:        DUPlicate the stack's top element                       */
 | 
| +  /* Opcode range: 0x20                                                    */
 | 
| +  /* Stack:        StkElt --> StkElt StkElt                                */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_DUP( FT_Long*  args )
 | 
| +  {
 | 
| +    args[1] = args[0];
 | 
| +  }
 | 
|  
 | 
| -    NORMalize( A, B, Vec );
 | 
|  
 | 
| -    return SUCCESS;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* POP[]:        POP the stack's top element                             */
 | 
| +  /* Opcode range: 0x21                                                    */
 | 
| +  /* Stack:        StkElt -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_POP( void )
 | 
| +  {
 | 
| +    /* nothing to do */
 | 
|    }
 | 
|  
 | 
|  
 | 
| -  /* When not using the big switch statements, the interpreter uses a */
 | 
| -  /* call table defined later below in this source.  Each opcode must */
 | 
| -  /* thus have a corresponding function, even trivial ones.           */
 | 
| -  /*                                                                  */
 | 
| -  /* They are all defined there.                                      */
 | 
| -
 | 
| -#define DO_SVTCA                            \
 | 
| -  {                                         \
 | 
| -    FT_Short  A, B;                         \
 | 
| -                                            \
 | 
| -                                            \
 | 
| -    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
 | 
| -    B = A ^ (FT_Short)0x4000;               \
 | 
| -                                            \
 | 
| -    CUR.GS.freeVector.x = A;                \
 | 
| -    CUR.GS.projVector.x = A;                \
 | 
| -    CUR.GS.dualVector.x = A;                \
 | 
| -                                            \
 | 
| -    CUR.GS.freeVector.y = B;                \
 | 
| -    CUR.GS.projVector.y = B;                \
 | 
| -    CUR.GS.dualVector.y = B;                \
 | 
| -                                            \
 | 
| -    COMPUTE_Funcs();                        \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_SPVTCA                           \
 | 
| -  {                                         \
 | 
| -    FT_Short  A, B;                         \
 | 
| -                                            \
 | 
| -                                            \
 | 
| -    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
 | 
| -    B = A ^ (FT_Short)0x4000;               \
 | 
| -                                            \
 | 
| -    CUR.GS.projVector.x = A;                \
 | 
| -    CUR.GS.dualVector.x = A;                \
 | 
| -                                            \
 | 
| -    CUR.GS.projVector.y = B;                \
 | 
| -    CUR.GS.dualVector.y = B;                \
 | 
| -                                            \
 | 
| -    GUESS_VECTOR( freeVector );             \
 | 
| -                                            \
 | 
| -    COMPUTE_Funcs();                        \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_SFVTCA                           \
 | 
| -  {                                         \
 | 
| -    FT_Short  A, B;                         \
 | 
| -                                            \
 | 
| -                                            \
 | 
| -    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
 | 
| -    B = A ^ (FT_Short)0x4000;               \
 | 
| -                                            \
 | 
| -    CUR.GS.freeVector.x = A;                \
 | 
| -    CUR.GS.freeVector.y = B;                \
 | 
| -                                            \
 | 
| -    GUESS_VECTOR( projVector );             \
 | 
| -                                            \
 | 
| -    COMPUTE_Funcs();                        \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_SPVTL                                      \
 | 
| -    if ( INS_SxVTL( (FT_UShort)args[1],               \
 | 
| -                    (FT_UShort)args[0],               \
 | 
| -                    CUR.opcode,                       \
 | 
| -                    &CUR.GS.projVector ) == SUCCESS ) \
 | 
| -    {                                                 \
 | 
| -      CUR.GS.dualVector = CUR.GS.projVector;          \
 | 
| -      GUESS_VECTOR( freeVector );                     \
 | 
| -      COMPUTE_Funcs();                                \
 | 
| -    }
 | 
| -
 | 
| -
 | 
| -#define DO_SFVTL                                      \
 | 
| -    if ( INS_SxVTL( (FT_UShort)args[1],               \
 | 
| -                    (FT_UShort)args[0],               \
 | 
| -                    CUR.opcode,                       \
 | 
| -                    &CUR.GS.freeVector ) == SUCCESS ) \
 | 
| -    {                                                 \
 | 
| -      GUESS_VECTOR( projVector );                     \
 | 
| -      COMPUTE_Funcs();                                \
 | 
| -    }
 | 
| -
 | 
| -
 | 
| -#define DO_SFVTPV                          \
 | 
| -    GUESS_VECTOR( projVector );            \
 | 
| -    CUR.GS.freeVector = CUR.GS.projVector; \
 | 
| -    COMPUTE_Funcs();
 | 
| -
 | 
| -
 | 
| -#define DO_SPVFS                                \
 | 
| -  {                                             \
 | 
| -    FT_Short  S;                                \
 | 
| -    FT_Long   X, Y;                             \
 | 
| -                                                \
 | 
| -                                                \
 | 
| -    /* Only use low 16bits, then sign extend */ \
 | 
| -    S = (FT_Short)args[1];                      \
 | 
| -    Y = (FT_Long)S;                             \
 | 
| -    S = (FT_Short)args[0];                      \
 | 
| -    X = (FT_Long)S;                             \
 | 
| -                                                \
 | 
| -    NORMalize( X, Y, &CUR.GS.projVector );      \
 | 
| -                                                \
 | 
| -    CUR.GS.dualVector = CUR.GS.projVector;      \
 | 
| -    GUESS_VECTOR( freeVector );                 \
 | 
| -    COMPUTE_Funcs();                            \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_SFVFS                                \
 | 
| -  {                                             \
 | 
| -    FT_Short  S;                                \
 | 
| -    FT_Long   X, Y;                             \
 | 
| -                                                \
 | 
| -                                                \
 | 
| -    /* Only use low 16bits, then sign extend */ \
 | 
| -    S = (FT_Short)args[1];                      \
 | 
| -    Y = (FT_Long)S;                             \
 | 
| -    S = (FT_Short)args[0];                      \
 | 
| -    X = S;                                      \
 | 
| -                                                \
 | 
| -    NORMalize( X, Y, &CUR.GS.freeVector );      \
 | 
| -    GUESS_VECTOR( projVector );                 \
 | 
| -    COMPUTE_Funcs();                            \
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* CLEAR[]:      CLEAR the entire stack                                  */
 | 
| +  /* Opcode range: 0x22                                                    */
 | 
| +  /* Stack:        StkElt... -->                                           */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_CLEAR( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->new_top = 0;
 | 
|    }
 | 
|  
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -#define DO_GPV                                   \
 | 
| -    if ( CUR.face->unpatented_hinting )          \
 | 
| -    {                                            \
 | 
| -      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
 | 
| -      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
 | 
| -    }                                            \
 | 
| -    else                                         \
 | 
| -    {                                            \
 | 
| -      args[0] = CUR.GS.projVector.x;             \
 | 
| -      args[1] = CUR.GS.projVector.y;             \
 | 
| -    }
 | 
| -#else
 | 
| -#define DO_GPV                                   \
 | 
| -    args[0] = CUR.GS.projVector.x;               \
 | 
| -    args[1] = CUR.GS.projVector.y;
 | 
| -#endif
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SWAP[]:       SWAP the stack's top two elements                       */
 | 
| +  /* Opcode range: 0x23                                                    */
 | 
| +  /* Stack:        2 * StkElt --> 2 * StkElt                               */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SWAP( FT_Long*  args )
 | 
| +  {
 | 
| +    FT_Long  L;
 | 
|  
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -#define DO_GFV                                   \
 | 
| -    if ( CUR.face->unpatented_hinting )          \
 | 
| -    {                                            \
 | 
| -      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
 | 
| -      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
 | 
| -    }                                            \
 | 
| -    else                                         \
 | 
| -    {                                            \
 | 
| -      args[0] = CUR.GS.freeVector.x;             \
 | 
| -      args[1] = CUR.GS.freeVector.y;             \
 | 
| -    }
 | 
| -#else
 | 
| -#define DO_GFV                                   \
 | 
| -    args[0] = CUR.GS.freeVector.x;               \
 | 
| -    args[1] = CUR.GS.freeVector.y;
 | 
| -#endif
 | 
| +    L       = args[0];
 | 
| +    args[0] = args[1];
 | 
| +    args[1] = L;
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_SRP0                      \
 | 
| -    CUR.GS.rp0 = (FT_UShort)args[0];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* DEPTH[]:      return the stack DEPTH                                  */
 | 
| +  /* Opcode range: 0x24                                                    */
 | 
| +  /* Stack:        --> uint32                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_DEPTH( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    args[0] = exc->top;
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_SRP1                      \
 | 
| -    CUR.GS.rp1 = (FT_UShort)args[0];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* LT[]:         Less Than                                               */
 | 
| +  /* Opcode range: 0x50                                                    */
 | 
| +  /* Stack:        int32? int32? --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_LT( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] < args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_SRP2                      \
 | 
| -    CUR.GS.rp2 = (FT_UShort)args[0];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* LTEQ[]:       Less Than or EQual                                      */
 | 
| +  /* Opcode range: 0x51                                                    */
 | 
| +  /* Stack:        int32? int32? --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_LTEQ( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] <= args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_RTHG                                         \
 | 
| -    CUR.GS.round_state = TT_Round_To_Half_Grid;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* GT[]:         Greater Than                                            */
 | 
| +  /* Opcode range: 0x52                                                    */
 | 
| +  /* Stack:        int32? int32? --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_GT( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] > args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_RTG                                     \
 | 
| -    CUR.GS.round_state = TT_Round_To_Grid;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_To_Grid;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* GTEQ[]:       Greater Than or EQual                                   */
 | 
| +  /* Opcode range: 0x53                                                    */
 | 
| +  /* Stack:        int32? int32? --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_GTEQ( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] >= args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_RTDG                                           \
 | 
| -    CUR.GS.round_state = TT_Round_To_Double_Grid;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* EQ[]:         EQual                                                   */
 | 
| +  /* Opcode range: 0x54                                                    */
 | 
| +  /* Stack:        StkElt StkElt --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_EQ( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] == args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -#define DO_RUTG                                       \
 | 
| -    CUR.GS.round_state = TT_Round_Up_To_Grid;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
 | 
| -
 | 
| -
 | 
| -#define DO_RDTG                                         \
 | 
| -    CUR.GS.round_state = TT_Round_Down_To_Grid;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
 | 
| -
 | 
| -
 | 
| -#define DO_ROFF                                 \
 | 
| -    CUR.GS.round_state = TT_Round_Off;          \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_None;
 | 
| -
 | 
| -
 | 
| -#define DO_SROUND                                \
 | 
| -    SET_SuperRound( 0x4000, args[0] );           \
 | 
| -    CUR.GS.round_state = TT_Round_Super;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_Super;
 | 
| -
 | 
| -
 | 
| -#define DO_S45ROUND                                 \
 | 
| -    SET_SuperRound( 0x2D41, args[0] );              \
 | 
| -    CUR.GS.round_state = TT_Round_Super_45;         \
 | 
| -    CUR.func_round = (TT_Round_Func)Round_Super_45;
 | 
| -
 | 
| -
 | 
| -#define DO_SLOOP                            \
 | 
| -    if ( args[0] < 0 )                      \
 | 
| -      CUR.error = FT_THROW( Bad_Argument ); \
 | 
| -    else                                    \
 | 
| -      CUR.GS.loop = args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_SMD                         \
 | 
| -    CUR.GS.minimum_distance = args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_SCVTCI                                     \
 | 
| -    CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_SSWCI                                     \
 | 
| -    CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_SSW                                                     \
 | 
| -    CUR.GS.single_width_value = FT_MulFix( args[0],                \
 | 
| -                                           CUR.tt_metrics.scale );
 | 
| -
 | 
| -
 | 
| -#define DO_FLIPON            \
 | 
| -    CUR.GS.auto_flip = TRUE;
 | 
| -
 | 
| -
 | 
| -#define DO_FLIPOFF            \
 | 
| -    CUR.GS.auto_flip = FALSE;
 | 
| -
 | 
| -
 | 
| -#define DO_SDB                              \
 | 
| -    CUR.GS.delta_base = (FT_UShort)args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_SDS                                 \
 | 
| -    if ( (FT_ULong)args[0] > 6UL )             \
 | 
| -      CUR.error = FT_THROW( Bad_Argument );    \
 | 
| -    else                                       \
 | 
| -      CUR.GS.delta_shift = (FT_UShort)args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_MD  /* nothing */
 | 
| -
 | 
| -
 | 
| -#define DO_MPPEM              \
 | 
| -    args[0] = CUR_Func_cur_ppem();
 | 
| -
 | 
| -
 | 
| -  /* Note: The pointSize should be irrelevant in a given font program; */
 | 
| -  /*       we thus decide to return only the ppem.                     */
 | 
| -#if 0
 | 
| -
 | 
| -#define DO_MPS                       \
 | 
| -    args[0] = CUR.metrics.pointSize;
 | 
| -
 | 
| -#else
 | 
| -
 | 
| -#define DO_MPS                \
 | 
| -    args[0] = CUR_Func_cur_ppem();
 | 
| -
 | 
| -#endif /* 0 */
 | 
| -
 | 
| -
 | 
| -#define DO_DUP         \
 | 
| -    args[1] = args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_CLEAR     \
 | 
| -    CUR.new_top = 0;
 | 
| -
 | 
| -
 | 
| -#define DO_SWAP        \
 | 
| -  {                    \
 | 
| -    FT_Long  L;        \
 | 
| -                       \
 | 
| -                       \
 | 
| -    L       = args[0]; \
 | 
| -    args[0] = args[1]; \
 | 
| -    args[1] = L;       \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_DEPTH       \
 | 
| -    args[0] = CUR.top;
 | 
| -
 | 
| -
 | 
| -#define DO_CINDEX                                  \
 | 
| -  {                                                \
 | 
| -    FT_Long  L;                                    \
 | 
| -                                                   \
 | 
| -                                                   \
 | 
| -    L = args[0];                                   \
 | 
| -                                                   \
 | 
| -    if ( L <= 0 || L > CUR.args )                  \
 | 
| -    {                                              \
 | 
| -      if ( CUR.pedantic_hinting )                  \
 | 
| -        CUR.error = FT_THROW( Invalid_Reference ); \
 | 
| -      args[0] = 0;                                 \
 | 
| -    }                                              \
 | 
| -    else                                           \
 | 
| -      args[0] = CUR.stack[CUR.args - L];           \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -#define DO_JROT                                                    \
 | 
| -    if ( args[1] != 0 )                                            \
 | 
| -    {                                                              \
 | 
| -      if ( args[0] == 0 && CUR.args == 0 )                         \
 | 
| -        CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -      CUR.IP += args[0];                                           \
 | 
| -      if ( CUR.IP < 0                                           || \
 | 
| -           ( CUR.callTop > 0                                  &&   \
 | 
| -             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
 | 
| -        CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -      CUR.step_ins = FALSE;                                        \
 | 
| -    }
 | 
| -
 | 
| -
 | 
| -#define DO_JMPR                                                  \
 | 
| -    if ( args[0] == 0 && CUR.args == 0 )                         \
 | 
| -      CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -    CUR.IP += args[0];                                           \
 | 
| -    if ( CUR.IP < 0                                           || \
 | 
| -         ( CUR.callTop > 0                                  &&   \
 | 
| -           CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
 | 
| -      CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -    CUR.step_ins = FALSE;
 | 
| -
 | 
| -
 | 
| -#define DO_JROF                                                    \
 | 
| -    if ( args[1] == 0 )                                            \
 | 
| -    {                                                              \
 | 
| -      if ( args[0] == 0 && CUR.args == 0 )                         \
 | 
| -        CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -      CUR.IP += args[0];                                           \
 | 
| -      if ( CUR.IP < 0                                           || \
 | 
| -           ( CUR.callTop > 0                                  &&   \
 | 
| -             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
 | 
| -        CUR.error = FT_THROW( Bad_Argument );                      \
 | 
| -      CUR.step_ins = FALSE;                                        \
 | 
| -    }
 | 
| -
 | 
| -
 | 
| -#define DO_LT                        \
 | 
| -    args[0] = ( args[0] < args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_LTEQ                       \
 | 
| -    args[0] = ( args[0] <= args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_GT                        \
 | 
| -    args[0] = ( args[0] > args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_GTEQ                       \
 | 
| -    args[0] = ( args[0] >= args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_EQ                         \
 | 
| -    args[0] = ( args[0] == args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_NEQ                        \
 | 
| -    args[0] = ( args[0] != args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_ODD                                                  \
 | 
| -    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
 | 
| -
 | 
| -
 | 
| -#define DO_EVEN                                                \
 | 
| -    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
 | 
| -
 | 
| -
 | 
| -#define DO_AND                        \
 | 
| -    args[0] = ( args[0] && args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_OR                         \
 | 
| -    args[0] = ( args[0] || args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_NOT          \
 | 
| -    args[0] = !args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_ADD          \
 | 
| -    args[0] += args[1];
 | 
| -
 | 
| -
 | 
| -#define DO_SUB          \
 | 
| -    args[0] -= args[1];
 | 
| -
 | 
| -
 | 
| -#define DO_DIV                                               \
 | 
| -    if ( args[1] == 0 )                                      \
 | 
| -      CUR.error = FT_THROW( Divide_By_Zero );                \
 | 
| -    else                                                     \
 | 
| -      args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
 | 
| -
 | 
| -
 | 
| -#define DO_MUL                                    \
 | 
| -    args[0] = FT_MulDiv( args[0], args[1], 64L );
 | 
| -
 | 
| -
 | 
| -#define DO_ABS                   \
 | 
| -    args[0] = FT_ABS( args[0] );
 | 
| -
 | 
| -
 | 
| -#define DO_NEG          \
 | 
| -    args[0] = -args[0];
 | 
| -
 | 
| -
 | 
| -#define DO_FLOOR    \
 | 
| -    args[0] = FT_PIX_FLOOR( args[0] );
 | 
| -
 | 
| -
 | 
| -#define DO_CEILING                    \
 | 
| -    args[0] = FT_PIX_CEIL( args[0] );
 | 
| -
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -
 | 
| -#define DO_RS                                             \
 | 
| -   {                                                      \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];                     \
 | 
| -                                                          \
 | 
| -                                                          \
 | 
| -     if ( BOUNDSL( I, CUR.storeSize ) )                   \
 | 
| -     {                                                    \
 | 
| -       if ( CUR.pedantic_hinting )                        \
 | 
| -         ARRAY_BOUND_ERROR;                               \
 | 
| -       else                                               \
 | 
| -         args[0] = 0;                                     \
 | 
| -     }                                                    \
 | 
| -     else                                                 \
 | 
| -     {                                                    \
 | 
| -       /* subpixel hinting - avoid Typeman Dstroke and */ \
 | 
| -       /* IStroke and Vacuform rounds                  */ \
 | 
| -                                                          \
 | 
| -       if ( SUBPIXEL_HINTING                           && \
 | 
| -            CUR.ignore_x_mode                          && \
 | 
| -            ( ( I == 24                            &&     \
 | 
| -                ( CUR.face->sph_found_func_flags &        \
 | 
| -                  ( SPH_FDEF_SPACING_1 |                  \
 | 
| -                    SPH_FDEF_SPACING_2 )         ) ) ||   \
 | 
| -              ( I == 22                      &&           \
 | 
| -                ( CUR.sph_in_func_flags    &              \
 | 
| -                  SPH_FDEF_TYPEMAN_STROKES ) )       ||   \
 | 
| -              ( I == 8                             &&     \
 | 
| -                ( CUR.face->sph_found_func_flags &        \
 | 
| -                  SPH_FDEF_VACUFORM_ROUND_1      ) &&     \
 | 
| -                  CUR.iup_called                   ) ) )  \
 | 
| -         args[0] = 0;                                     \
 | 
| -       else                                               \
 | 
| -         args[0] = CUR.storage[I];                        \
 | 
| -     }                                                    \
 | 
| -   }
 | 
| -
 | 
| -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| -
 | 
| -#define DO_RS                           \
 | 
| -   {                                    \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];   \
 | 
| -                                        \
 | 
| -                                        \
 | 
| -     if ( BOUNDSL( I, CUR.storeSize ) ) \
 | 
| -     {                                  \
 | 
| -       if ( CUR.pedantic_hinting )      \
 | 
| -       {                                \
 | 
| -         ARRAY_BOUND_ERROR;             \
 | 
| -       }                                \
 | 
| -       else                             \
 | 
| -         args[0] = 0;                   \
 | 
| -     }                                  \
 | 
| -     else                               \
 | 
| -       args[0] = CUR.storage[I];        \
 | 
| -   }
 | 
| -
 | 
| -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| -
 | 
| -
 | 
| -#define DO_WS                           \
 | 
| -   {                                    \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];   \
 | 
| -                                        \
 | 
| -                                        \
 | 
| -     if ( BOUNDSL( I, CUR.storeSize ) ) \
 | 
| -     {                                  \
 | 
| -       if ( CUR.pedantic_hinting )      \
 | 
| -       {                                \
 | 
| -         ARRAY_BOUND_ERROR;             \
 | 
| -       }                                \
 | 
| -     }                                  \
 | 
| -     else                               \
 | 
| -       CUR.storage[I] = args[1];        \
 | 
| -   }
 | 
| -
 | 
| -
 | 
| -#define DO_RCVT                          \
 | 
| -   {                                     \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];    \
 | 
| -                                         \
 | 
| -                                         \
 | 
| -     if ( BOUNDSL( I, CUR.cvtSize ) )    \
 | 
| -     {                                   \
 | 
| -       if ( CUR.pedantic_hinting )       \
 | 
| -       {                                 \
 | 
| -         ARRAY_BOUND_ERROR;              \
 | 
| -       }                                 \
 | 
| -       else                              \
 | 
| -         args[0] = 0;                    \
 | 
| -     }                                   \
 | 
| -     else                                \
 | 
| -       args[0] = CUR_Func_read_cvt( I ); \
 | 
| -   }
 | 
| -
 | 
| -
 | 
| -#define DO_WCVTP                         \
 | 
| -   {                                     \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];    \
 | 
| -                                         \
 | 
| -                                         \
 | 
| -     if ( BOUNDSL( I, CUR.cvtSize ) )    \
 | 
| -     {                                   \
 | 
| -       if ( CUR.pedantic_hinting )       \
 | 
| -       {                                 \
 | 
| -         ARRAY_BOUND_ERROR;              \
 | 
| -       }                                 \
 | 
| -     }                                   \
 | 
| -     else                                \
 | 
| -       CUR_Func_write_cvt( I, args[1] ); \
 | 
| -   }
 | 
| -
 | 
| -
 | 
| -#define DO_WCVTF                                                \
 | 
| -   {                                                            \
 | 
| -     FT_ULong  I = (FT_ULong)args[0];                           \
 | 
| -                                                                \
 | 
| -                                                                \
 | 
| -     if ( BOUNDSL( I, CUR.cvtSize ) )                           \
 | 
| -     {                                                          \
 | 
| -       if ( CUR.pedantic_hinting )                              \
 | 
| -       {                                                        \
 | 
| -         ARRAY_BOUND_ERROR;                                     \
 | 
| -       }                                                        \
 | 
| -     }                                                          \
 | 
| -     else                                                       \
 | 
| -       CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
 | 
| -   }
 | 
| -
 | 
| -
 | 
| -#define DO_DEBUG                          \
 | 
| -    CUR.error = FT_THROW( Debug_OpCode );
 | 
| -
 | 
| -
 | 
| -#define DO_ROUND                                                   \
 | 
| -    args[0] = CUR_Func_round(                                      \
 | 
| -                args[0],                                           \
 | 
| -                CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
 | 
| -
 | 
| -
 | 
| -#define DO_NROUND                                                            \
 | 
| -    args[0] = ROUND_None( args[0],                                           \
 | 
| -                          CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
 | 
| -
 | 
| -
 | 
| -#define DO_MAX               \
 | 
| -    if ( args[1] > args[0] ) \
 | 
| -      args[0] = args[1];
 | 
| -
 | 
| -
 | 
| -#define DO_MIN               \
 | 
| -    if ( args[1] < args[0] ) \
 | 
| -      args[0] = args[1];
 | 
| -
 | 
| -
 | 
| -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
 | 
| -
 | 
| -
 | 
| -#undef  ARRAY_BOUND_ERROR
 | 
| -#define ARRAY_BOUND_ERROR                        \
 | 
| -    {                                            \
 | 
| -      CUR.error = FT_THROW( Invalid_Reference ); \
 | 
| -      return;                                    \
 | 
| -    }
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* NEQ[]:        Not EQual                                               */
 | 
| +  /* Opcode range: 0x55                                                    */
 | 
| +  /* Stack:        StkElt StkElt --> bool                                  */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_NEQ( FT_Long*  args )
 | 
| +  {
 | 
| +    args[0] = ( args[0] != args[1] );
 | 
| +  }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
 | 
| -  /* Opcode range: 0x00-0x01                                               */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* ODD[]:        Is ODD                                                  */
 | 
| +  /* Opcode range: 0x56                                                    */
 | 
| +  /* Stack:        f26.6 --> bool                                          */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SVTCA( INS_ARG )
 | 
| +  Ins_ODD( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
| -    DO_SVTCA
 | 
| +    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SPVTCA[a]:    Set PVector to Coordinate Axis                          */
 | 
| -  /* Opcode range: 0x02-0x03                                               */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* EVEN[]:       Is EVEN                                                 */
 | 
| +  /* Opcode range: 0x57                                                    */
 | 
| +  /* Stack:        f26.6 --> bool                                          */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SPVTCA( INS_ARG )
 | 
| +  Ins_EVEN( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    DO_SPVTCA
 | 
| +    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SFVTCA[a]:    Set FVector to Coordinate Axis                          */
 | 
| -  /* Opcode range: 0x04-0x05                                               */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* AND[]:        logical AND                                             */
 | 
| +  /* Opcode range: 0x5A                                                    */
 | 
| +  /* Stack:        uint32 uint32 --> uint32                                */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SFVTCA( INS_ARG )
 | 
| +  Ins_AND( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SFVTCA
 | 
| +    args[0] = ( args[0] && args[1] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SPVTL[a]:     Set PVector To Line                                     */
 | 
| -  /* Opcode range: 0x06-0x07                                               */
 | 
| -  /* Stack:        uint32 uint32 -->                                       */
 | 
| +  /* OR[]:         logical OR                                              */
 | 
| +  /* Opcode range: 0x5B                                                    */
 | 
| +  /* Stack:        uint32 uint32 --> uint32                                */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SPVTL( INS_ARG )
 | 
| +  Ins_OR( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SPVTL
 | 
| +    args[0] = ( args[0] || args[1] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SFVTL[a]:     Set FVector To Line                                     */
 | 
| -  /* Opcode range: 0x08-0x09                                               */
 | 
| -  /* Stack:        uint32 uint32 -->                                       */
 | 
| +  /* NOT[]:        logical NOT                                             */
 | 
| +  /* Opcode range: 0x5C                                                    */
 | 
| +  /* Stack:        StkElt --> uint32                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SFVTL( INS_ARG )
 | 
| +  Ins_NOT( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SFVTL
 | 
| +    args[0] = !args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SFVTPV[]:     Set FVector To PVector                                  */
 | 
| -  /* Opcode range: 0x0E                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* ADD[]:        ADD                                                     */
 | 
| +  /* Opcode range: 0x60                                                    */
 | 
| +  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SFVTPV( INS_ARG )
 | 
| +  Ins_ADD( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SFVTPV
 | 
| +    args[0] += args[1];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SPVFS[]:      Set PVector From Stack                                  */
 | 
| -  /* Opcode range: 0x0A                                                    */
 | 
| -  /* Stack:        f2.14 f2.14 -->                                         */
 | 
| +  /* SUB[]:        SUBtract                                                */
 | 
| +  /* Opcode range: 0x61                                                    */
 | 
| +  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SPVFS( INS_ARG )
 | 
| +  Ins_SUB( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SPVFS
 | 
| +    args[0] -= args[1];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SFVFS[]:      Set FVector From Stack                                  */
 | 
| -  /* Opcode range: 0x0B                                                    */
 | 
| -  /* Stack:        f2.14 f2.14 -->                                         */
 | 
| +  /* DIV[]:        DIVide                                                  */
 | 
| +  /* Opcode range: 0x62                                                    */
 | 
| +  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SFVFS( INS_ARG )
 | 
| +  Ins_DIV( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
| -    DO_SFVFS
 | 
| +    if ( args[1] == 0 )
 | 
| +      exc->error = FT_THROW( Divide_By_Zero );
 | 
| +    else
 | 
| +      args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* GPV[]:        Get Projection Vector                                   */
 | 
| -  /* Opcode range: 0x0C                                                    */
 | 
| -  /* Stack:        ef2.14 --> ef2.14                                       */
 | 
| +  /* MUL[]:        MULtiply                                                */
 | 
| +  /* Opcode range: 0x63                                                    */
 | 
| +  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_GPV( INS_ARG )
 | 
| +  Ins_MUL( FT_Long*  args )
 | 
|    {
 | 
| -    DO_GPV
 | 
| +    args[0] = FT_MulDiv( args[0], args[1], 64L );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
| -  /* GFV[]:        Get Freedom Vector                                      */
 | 
| -  /* Opcode range: 0x0D                                                    */
 | 
| -  /* Stack:        ef2.14 --> ef2.14                                       */
 | 
| +  /*                                                                       */
 | 
| +  /* ABS[]:        ABSolute value                                          */
 | 
| +  /* Opcode range: 0x64                                                    */
 | 
| +  /* Stack:        f26.6 --> f26.6                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_GFV( INS_ARG )
 | 
| +  Ins_ABS( FT_Long*  args )
 | 
|    {
 | 
| -    DO_GFV
 | 
| +    args[0] = FT_ABS( args[0] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SRP0[]:       Set Reference Point 0                                   */
 | 
| -  /* Opcode range: 0x10                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* NEG[]:        NEGate                                                  */
 | 
| +  /* Opcode range: 0x65                                                    */
 | 
| +  /* Stack: f26.6 --> f26.6                                                */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SRP0( INS_ARG )
 | 
| +  Ins_NEG( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SRP0
 | 
| +    args[0] = -args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SRP1[]:       Set Reference Point 1                                   */
 | 
| -  /* Opcode range: 0x11                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* FLOOR[]:      FLOOR                                                   */
 | 
| +  /* Opcode range: 0x66                                                    */
 | 
| +  /* Stack:        f26.6 --> f26.6                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SRP1( INS_ARG )
 | 
| +  Ins_FLOOR( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SRP1
 | 
| +    args[0] = FT_PIX_FLOOR( args[0] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SRP2[]:       Set Reference Point 2                                   */
 | 
| -  /* Opcode range: 0x12                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* CEILING[]:    CEILING                                                 */
 | 
| +  /* Opcode range: 0x67                                                    */
 | 
| +  /* Stack:        f26.6 --> f26.6                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SRP2( INS_ARG )
 | 
| +  Ins_CEILING( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SRP2
 | 
| +    args[0] = FT_PIX_CEIL( args[0] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* RTHG[]:       Round To Half Grid                                      */
 | 
| -  /* Opcode range: 0x19                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* RS[]:         Read Store                                              */
 | 
| +  /* Opcode range: 0x43                                                    */
 | 
| +  /* Stack:        uint32 --> uint32                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_RTHG( INS_ARG )
 | 
| +  Ins_RS( TT_ExecContext  exc,
 | 
| +          FT_Long*        args )
 | 
|    {
 | 
| -    DO_RTHG
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
| +
 | 
| +
 | 
| +    if ( BOUNDSL( I, exc->storeSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +      else
 | 
| +        args[0] = 0;
 | 
| +    }
 | 
| +    else
 | 
| +    {
 | 
| +      /* subpixel hinting - avoid Typeman Dstroke and */
 | 
| +      /* IStroke and Vacuform rounds                  */
 | 
| +      if ( SUBPIXEL_HINTING                            &&
 | 
| +           exc->ignore_x_mode                          &&
 | 
| +           ( ( I == 24                             &&
 | 
| +               ( exc->face->sph_found_func_flags &
 | 
| +                 ( SPH_FDEF_SPACING_1 |
 | 
| +                   SPH_FDEF_SPACING_2 )          ) ) ||
 | 
| +             ( I == 22                      &&
 | 
| +               ( exc->sph_in_func_flags   &
 | 
| +                 SPH_FDEF_TYPEMAN_STROKES ) )        ||
 | 
| +             ( I == 8                              &&
 | 
| +               ( exc->face->sph_found_func_flags &
 | 
| +                 SPH_FDEF_VACUFORM_ROUND_1       ) &&
 | 
| +               exc->iup_called                     ) ) )
 | 
| +        args[0] = 0;
 | 
| +      else
 | 
| +        args[0] = exc->storage[I];
 | 
| +    }
 | 
| +
 | 
| +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| +
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
| +
 | 
| +
 | 
| +    if ( BOUNDSL( I, exc->storeSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +      else
 | 
| +        args[0] = 0;
 | 
| +    }
 | 
| +    else
 | 
| +      args[0] = exc->storage[I];
 | 
| +
 | 
| +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* RTG[]:        Round To Grid                                           */
 | 
| -  /* Opcode range: 0x18                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* WS[]:         Write Store                                             */
 | 
| +  /* Opcode range: 0x42                                                    */
 | 
| +  /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_RTG( INS_ARG )
 | 
| +  Ins_WS( TT_ExecContext  exc,
 | 
| +          FT_Long*        args )
 | 
|    {
 | 
| -    DO_RTG
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
| +
 | 
| +
 | 
| +    if ( BOUNDSL( I, exc->storeSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +    }
 | 
| +    else
 | 
| +      exc->storage[I] = args[1];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
| -  /* RTDG[]:       Round To Double Grid                                    */
 | 
| -  /* Opcode range: 0x3D                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  /* WCVTP[]:      Write CVT in Pixel units                                */
 | 
| +  /* Opcode range: 0x44                                                    */
 | 
| +  /* Stack:        f26.6 uint32 -->                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_RTDG( INS_ARG )
 | 
| +  Ins_WCVTP( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    DO_RTDG
 | 
| -  }
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
|  
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /* RUTG[]:       Round Up To Grid                                        */
 | 
| -  /* Opcode range: 0x7C                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_RUTG( INS_ARG )
 | 
| -  {
 | 
| -    DO_RUTG
 | 
| +    if ( BOUNDSL( I, exc->cvtSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +    }
 | 
| +    else
 | 
| +      exc->func_write_cvt( exc, I, args[1] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* RDTG[]:       Round Down To Grid                                      */
 | 
| -  /* Opcode range: 0x7D                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* WCVTF[]:      Write CVT in Funits                                     */
 | 
| +  /* Opcode range: 0x70                                                    */
 | 
| +  /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_RDTG( INS_ARG )
 | 
| +  Ins_WCVTF( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    DO_RDTG
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
| +
 | 
| +
 | 
| +    if ( BOUNDSL( I, exc->cvtSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +    }
 | 
| +    else
 | 
| +      exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* ROFF[]:       Round OFF                                               */
 | 
| -  /* Opcode range: 0x7A                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* RCVT[]:       Read CVT                                                */
 | 
| +  /* Opcode range: 0x45                                                    */
 | 
| +  /* Stack:        uint32 --> f26.6                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_ROFF( INS_ARG )
 | 
| +  Ins_RCVT( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    DO_ROFF
 | 
| +    FT_ULong  I = (FT_ULong)args[0];
 | 
| +
 | 
| +
 | 
| +    if ( BOUNDSL( I, exc->cvtSize ) )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        ARRAY_BOUND_ERROR;
 | 
| +      else
 | 
| +        args[0] = 0;
 | 
| +    }
 | 
| +    else
 | 
| +      args[0] = exc->func_read_cvt( exc, I );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SROUND[]:     Super ROUND                                             */
 | 
| -  /* Opcode range: 0x76                                                    */
 | 
| -  /* Stack:        Eint8 -->                                               */
 | 
| +  /* AA[]:         Adjust Angle                                            */
 | 
| +  /* Opcode range: 0x7F                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SROUND( INS_ARG )
 | 
| +  Ins_AA( void )
 | 
|    {
 | 
| -    DO_SROUND
 | 
| +    /* intentionally no longer supported */
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* S45ROUND[]:   Super ROUND 45 degrees                                  */
 | 
| -  /* Opcode range: 0x77                                                    */
 | 
| +  /* DEBUG[]:      DEBUG.  Unsupported.                                    */
 | 
| +  /* Opcode range: 0x4F                                                    */
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
| +  /* Note: The original instruction pops a value from the stack.           */
 | 
| +  /*                                                                       */
 | 
|    static void
 | 
| -  Ins_S45ROUND( INS_ARG )
 | 
| +  Ins_DEBUG( TT_ExecContext  exc )
 | 
|    {
 | 
| -    DO_S45ROUND
 | 
| +    exc->error = FT_THROW( Debug_OpCode );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SLOOP[]:      Set LOOP variable                                       */
 | 
| -  /* Opcode range: 0x17                                                    */
 | 
| -  /* Stack:        int32? -->                                              */
 | 
| +  /* ROUND[ab]:    ROUND value                                             */
 | 
| +  /* Opcode range: 0x68-0x6B                                               */
 | 
| +  /* Stack:        f26.6 --> f26.6                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SLOOP( INS_ARG )
 | 
| +  Ins_ROUND( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    DO_SLOOP
 | 
| +    args[0] = exc->func_round(
 | 
| +                exc,
 | 
| +                args[0],
 | 
| +                exc->tt_metrics.compensations[exc->opcode - 0x68] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SMD[]:        Set Minimum Distance                                    */
 | 
| -  /* Opcode range: 0x1A                                                    */
 | 
| -  /* Stack:        f26.6 -->                                               */
 | 
| +  /* NROUND[ab]:   No ROUNDing of value                                    */
 | 
| +  /* Opcode range: 0x6C-0x6F                                               */
 | 
| +  /* Stack:        f26.6 --> f26.6                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SMD( INS_ARG )
 | 
| +  Ins_NROUND( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
| -    DO_SMD
 | 
| +    args[0] = Round_None(
 | 
| +                exc,
 | 
| +                args[0],
 | 
| +                exc->tt_metrics.compensations[exc->opcode - 0x6C] );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SCVTCI[]:     Set Control Value Table Cut In                          */
 | 
| -  /* Opcode range: 0x1D                                                    */
 | 
| -  /* Stack:        f26.6 -->                                               */
 | 
| +  /* MAX[]:        MAXimum                                                 */
 | 
| +  /* Opcode range: 0x68                                                    */
 | 
| +  /* Stack:        int32? int32? --> int32                                 */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SCVTCI( INS_ARG )
 | 
| +  Ins_MAX( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SCVTCI
 | 
| +    if ( args[1] > args[0] )
 | 
| +      args[0] = args[1];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SSWCI[]:      Set Single Width Cut In                                 */
 | 
| -  /* Opcode range: 0x1E                                                    */
 | 
| -  /* Stack:        f26.6 -->                                               */
 | 
| +  /* MIN[]:        MINimum                                                 */
 | 
| +  /* Opcode range: 0x69                                                    */
 | 
| +  /* Stack:        int32? int32? --> int32                                 */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SSWCI( INS_ARG )
 | 
| +  Ins_MIN( FT_Long*  args )
 | 
|    {
 | 
| -    DO_SSWCI
 | 
| +    if ( args[1] < args[0] )
 | 
| +      args[0] = args[1];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SSW[]:        Set Single Width                                        */
 | 
| -  /* Opcode range: 0x1F                                                    */
 | 
| -  /* Stack:        int32? -->                                              */
 | 
| +  /* MINDEX[]:     Move INDEXed element                                    */
 | 
| +  /* Opcode range: 0x26                                                    */
 | 
| +  /* Stack:        int32? --> StkElt                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SSW( INS_ARG )
 | 
| +  Ins_MINDEX( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
| -    DO_SSW
 | 
| +    FT_Long  L, K;
 | 
| +
 | 
| +
 | 
| +    L = args[0];
 | 
| +
 | 
| +    if ( L <= 0 || L > exc->args )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
| +    }
 | 
| +    else
 | 
| +    {
 | 
| +      K = exc->stack[exc->args - L];
 | 
| +
 | 
| +      FT_ARRAY_MOVE( &exc->stack[exc->args - L    ],
 | 
| +                     &exc->stack[exc->args - L + 1],
 | 
| +                     ( L - 1 ) );
 | 
| +
 | 
| +      exc->stack[exc->args - 1] = K;
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* FLIPON[]:     Set auto-FLIP to ON                                     */
 | 
| -  /* Opcode range: 0x4D                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* CINDEX[]:     Copy INDEXed element                                    */
 | 
| +  /* Opcode range: 0x25                                                    */
 | 
| +  /* Stack:        int32 --> StkElt                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FLIPON( INS_ARG )
 | 
| +  Ins_CINDEX( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
| -    DO_FLIPON
 | 
| +    FT_Long  L;
 | 
| +
 | 
| +
 | 
| +    L = args[0];
 | 
| +
 | 
| +    if ( L <= 0 || L > exc->args )
 | 
| +    {
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
| +      args[0] = 0;
 | 
| +    }
 | 
| +    else
 | 
| +      args[0] = exc->stack[exc->args - L];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
 | 
| -  /* Opcode range: 0x4E                                                    */
 | 
| -  /* Stack: -->                                                            */
 | 
| +  /* ROLL[]:       ROLL top three elements                                 */
 | 
| +  /* Opcode range: 0x8A                                                    */
 | 
| +  /* Stack:        3 * StkElt --> 3 * StkElt                               */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FLIPOFF( INS_ARG )
 | 
| +  Ins_ROLL( FT_Long*  args )
 | 
|    {
 | 
| -    DO_FLIPOFF
 | 
| +    FT_Long  A, B, C;
 | 
| +
 | 
| +
 | 
| +    A = args[2];
 | 
| +    B = args[1];
 | 
| +    C = args[0];
 | 
| +
 | 
| +    args[2] = C;
 | 
| +    args[1] = A;
 | 
| +    args[0] = B;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SANGW[]:      Set ANGle Weight                                        */
 | 
| -  /* Opcode range: 0x7E                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* MANAGING THE FLOW OF CONTROL                                          */
 | 
|    /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_SANGW( INS_ARG )
 | 
| -  {
 | 
| -    /* instruction not supported anymore */
 | 
| -  }
 | 
| +  /*************************************************************************/
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SDB[]:        Set Delta Base                                          */
 | 
| -  /* Opcode range: 0x5E                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* SLOOP[]:      Set LOOP variable                                       */
 | 
| +  /* Opcode range: 0x17                                                    */
 | 
| +  /* Stack:        int32? -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SDB( INS_ARG )
 | 
| +  Ins_SLOOP( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    DO_SDB
 | 
| +    if ( args[0] < 0 )
 | 
| +      exc->error = FT_THROW( Bad_Argument );
 | 
| +    else
 | 
| +      exc->GS.loop = args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* SDS[]:        Set Delta Shift                                         */
 | 
| -  /* Opcode range: 0x5F                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_SDS( INS_ARG )
 | 
| +  static FT_Bool
 | 
| +  SkipCode( TT_ExecContext  exc )
 | 
|    {
 | 
| -    DO_SDS
 | 
| +    exc->IP += exc->length;
 | 
| +
 | 
| +    if ( exc->IP < exc->codeSize )
 | 
| +    {
 | 
| +      exc->opcode = exc->code[exc->IP];
 | 
| +
 | 
| +      exc->length = opcode_length[exc->opcode];
 | 
| +      if ( exc->length < 0 )
 | 
| +      {
 | 
| +        if ( exc->IP + 1 >= exc->codeSize )
 | 
| +          goto Fail_Overflow;
 | 
| +        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
 | 
| +      }
 | 
| +
 | 
| +      if ( exc->IP + exc->length <= exc->codeSize )
 | 
| +        return SUCCESS;
 | 
| +    }
 | 
| +
 | 
| +  Fail_Overflow:
 | 
| +    exc->error = FT_THROW( Code_Overflow );
 | 
| +    return FAILURE;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* MPPEM[]:      Measure Pixel Per EM                                    */
 | 
| -  /* Opcode range: 0x4B                                                    */
 | 
| -  /* Stack:        --> Euint16                                             */
 | 
| +  /* IF[]:         IF test                                                 */
 | 
| +  /* Opcode range: 0x58                                                    */
 | 
| +  /* Stack:        StkElt -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MPPEM( INS_ARG )
 | 
| +  Ins_IF( TT_ExecContext  exc,
 | 
| +          FT_Long*        args )
 | 
|    {
 | 
| -    DO_MPPEM
 | 
| +    FT_Int   nIfs;
 | 
| +    FT_Bool  Out;
 | 
| +
 | 
| +
 | 
| +    if ( args[0] != 0 )
 | 
| +      return;
 | 
| +
 | 
| +    nIfs = 1;
 | 
| +    Out = 0;
 | 
| +
 | 
| +    do
 | 
| +    {
 | 
| +      if ( SkipCode( exc ) == FAILURE )
 | 
| +        return;
 | 
| +
 | 
| +      switch ( exc->opcode )
 | 
| +      {
 | 
| +      case 0x58:      /* IF */
 | 
| +        nIfs++;
 | 
| +        break;
 | 
| +
 | 
| +      case 0x1B:      /* ELSE */
 | 
| +        Out = FT_BOOL( nIfs == 1 );
 | 
| +        break;
 | 
| +
 | 
| +      case 0x59:      /* EIF */
 | 
| +        nIfs--;
 | 
| +        Out = FT_BOOL( nIfs == 0 );
 | 
| +        break;
 | 
| +      }
 | 
| +    } while ( Out == 0 );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* MPS[]:        Measure Point Size                                      */
 | 
| -  /* Opcode range: 0x4C                                                    */
 | 
| -  /* Stack:        --> Euint16                                             */
 | 
| +  /* ELSE[]:       ELSE                                                    */
 | 
| +  /* Opcode range: 0x1B                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MPS( INS_ARG )
 | 
| +  Ins_ELSE( TT_ExecContext  exc )
 | 
|    {
 | 
| -    DO_MPS
 | 
| +    FT_Int  nIfs;
 | 
| +
 | 
| +
 | 
| +    nIfs = 1;
 | 
| +
 | 
| +    do
 | 
| +    {
 | 
| +      if ( SkipCode( exc ) == FAILURE )
 | 
| +        return;
 | 
| +
 | 
| +      switch ( exc->opcode )
 | 
| +      {
 | 
| +      case 0x58:    /* IF */
 | 
| +        nIfs++;
 | 
| +        break;
 | 
| +
 | 
| +      case 0x59:    /* EIF */
 | 
| +        nIfs--;
 | 
| +        break;
 | 
| +      }
 | 
| +    } while ( nIfs != 0 );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* DUP[]:        DUPlicate the top stack's element                       */
 | 
| -  /* Opcode range: 0x20                                                    */
 | 
| -  /* Stack:        StkElt --> StkElt StkElt                                */
 | 
| +  /* EIF[]:        End IF                                                  */
 | 
| +  /* Opcode range: 0x59                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_DUP( INS_ARG )
 | 
| +  Ins_EIF( void )
 | 
|    {
 | 
| -    DO_DUP
 | 
| +    /* nothing to do */
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* POP[]:        POP the stack's top element                             */
 | 
| -  /* Opcode range: 0x21                                                    */
 | 
| -  /* Stack:        StkElt -->                                              */
 | 
| +  /* JMPR[]:       JuMP Relative                                           */
 | 
| +  /* Opcode range: 0x1C                                                    */
 | 
| +  /* Stack:        int32 -->                                               */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_POP( INS_ARG )
 | 
| +  Ins_JMPR( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    /* nothing to do */
 | 
| +    if ( args[0] == 0 && exc->args == 0 )
 | 
| +      exc->error = FT_THROW( Bad_Argument );
 | 
| +    exc->IP += args[0];
 | 
| +    if ( exc->IP < 0                                             ||
 | 
| +         ( exc->callTop > 0                                    &&
 | 
| +           exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
 | 
| +      exc->error = FT_THROW( Bad_Argument );
 | 
| +    exc->step_ins = FALSE;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* CLEAR[]:      CLEAR the entire stack                                  */
 | 
| -  /* Opcode range: 0x22                                                    */
 | 
| -  /* Stack:        StkElt... -->                                           */
 | 
| +  /* JROT[]:       Jump Relative On True                                   */
 | 
| +  /* Opcode range: 0x78                                                    */
 | 
| +  /* Stack:        StkElt int32 -->                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_CLEAR( INS_ARG )
 | 
| +  Ins_JROT( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    DO_CLEAR
 | 
| +    if ( args[1] != 0 )
 | 
| +      Ins_JMPR( exc, args );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SWAP[]:       SWAP the stack's top two elements                       */
 | 
| -  /* Opcode range: 0x23                                                    */
 | 
| -  /* Stack:        2 * StkElt --> 2 * StkElt                               */
 | 
| +  /* JROF[]:       Jump Relative On False                                  */
 | 
| +  /* Opcode range: 0x79                                                    */
 | 
| +  /* Stack:        StkElt int32 -->                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SWAP( INS_ARG )
 | 
| +  Ins_JROF( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    DO_SWAP
 | 
| +    if ( args[1] == 0 )
 | 
| +      Ins_JMPR( exc, args );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* DEPTH[]:      return the stack DEPTH                                  */
 | 
| -  /* Opcode range: 0x24                                                    */
 | 
| -  /* Stack:        --> uint32                                              */
 | 
| +  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
 | 
|    /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_DEPTH( INS_ARG )
 | 
| -  {
 | 
| -    DO_DEPTH
 | 
| -  }
 | 
| +  /*************************************************************************/
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* CINDEX[]:     Copy INDEXed element                                    */
 | 
| -  /* Opcode range: 0x25                                                    */
 | 
| -  /* Stack:        int32 --> StkElt                                        */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_CINDEX( INS_ARG )
 | 
| -  {
 | 
| -    DO_CINDEX
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* EIF[]:        End IF                                                  */
 | 
| -  /* Opcode range: 0x59                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_EIF( INS_ARG )
 | 
| -  {
 | 
| -    /* nothing to do */
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* JROT[]:       Jump Relative On True                                   */
 | 
| -  /* Opcode range: 0x78                                                    */
 | 
| -  /* Stack:        StkElt int32 -->                                        */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_JROT( INS_ARG )
 | 
| -  {
 | 
| -    DO_JROT
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* JMPR[]:       JuMP Relative                                           */
 | 
| -  /* Opcode range: 0x1C                                                    */
 | 
| -  /* Stack:        int32 -->                                               */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_JMPR( INS_ARG )
 | 
| -  {
 | 
| -    DO_JMPR
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* JROF[]:       Jump Relative On False                                  */
 | 
| -  /* Opcode range: 0x79                                                    */
 | 
| -  /* Stack:        StkElt int32 -->                                        */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_JROF( INS_ARG )
 | 
| -  {
 | 
| -    DO_JROF
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* LT[]:         Less Than                                               */
 | 
| -  /* Opcode range: 0x50                                                    */
 | 
| -  /* Stack:        int32? int32? --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_LT( INS_ARG )
 | 
| -  {
 | 
| -    DO_LT
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* LTEQ[]:       Less Than or EQual                                      */
 | 
| -  /* Opcode range: 0x51                                                    */
 | 
| -  /* Stack:        int32? int32? --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_LTEQ( INS_ARG )
 | 
| -  {
 | 
| -    DO_LTEQ
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* GT[]:         Greater Than                                            */
 | 
| -  /* Opcode range: 0x52                                                    */
 | 
| -  /* Stack:        int32? int32? --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_GT( INS_ARG )
 | 
| -  {
 | 
| -    DO_GT
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* GTEQ[]:       Greater Than or EQual                                   */
 | 
| -  /* Opcode range: 0x53                                                    */
 | 
| -  /* Stack:        int32? int32? --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_GTEQ( INS_ARG )
 | 
| -  {
 | 
| -    DO_GTEQ
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* EQ[]:         EQual                                                   */
 | 
| -  /* Opcode range: 0x54                                                    */
 | 
| -  /* Stack:        StkElt StkElt --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_EQ( INS_ARG )
 | 
| -  {
 | 
| -    DO_EQ
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* NEQ[]:        Not EQual                                               */
 | 
| -  /* Opcode range: 0x55                                                    */
 | 
| -  /* Stack:        StkElt StkElt --> bool                                  */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_NEQ( INS_ARG )
 | 
| -  {
 | 
| -    DO_NEQ
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ODD[]:        Is ODD                                                  */
 | 
| -  /* Opcode range: 0x56                                                    */
 | 
| -  /* Stack:        f26.6 --> bool                                          */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ODD( INS_ARG )
 | 
| -  {
 | 
| -    DO_ODD
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* EVEN[]:       Is EVEN                                                 */
 | 
| -  /* Opcode range: 0x57                                                    */
 | 
| -  /* Stack:        f26.6 --> bool                                          */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_EVEN( INS_ARG )
 | 
| -  {
 | 
| -    DO_EVEN
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* AND[]:        logical AND                                             */
 | 
| -  /* Opcode range: 0x5A                                                    */
 | 
| -  /* Stack:        uint32 uint32 --> uint32                                */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_AND( INS_ARG )
 | 
| -  {
 | 
| -    DO_AND
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* OR[]:         logical OR                                              */
 | 
| -  /* Opcode range: 0x5B                                                    */
 | 
| -  /* Stack:        uint32 uint32 --> uint32                                */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_OR( INS_ARG )
 | 
| -  {
 | 
| -    DO_OR
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* NOT[]:        logical NOT                                             */
 | 
| -  /* Opcode range: 0x5C                                                    */
 | 
| -  /* Stack:        StkElt --> uint32                                       */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_NOT( INS_ARG )
 | 
| -  {
 | 
| -    DO_NOT
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ADD[]:        ADD                                                     */
 | 
| -  /* Opcode range: 0x60                                                    */
 | 
| -  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ADD( INS_ARG )
 | 
| -  {
 | 
| -    DO_ADD
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* SUB[]:        SUBtract                                                */
 | 
| -  /* Opcode range: 0x61                                                    */
 | 
| -  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_SUB( INS_ARG )
 | 
| -  {
 | 
| -    DO_SUB
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* DIV[]:        DIVide                                                  */
 | 
| -  /* Opcode range: 0x62                                                    */
 | 
| -  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_DIV( INS_ARG )
 | 
| -  {
 | 
| -    DO_DIV
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* MUL[]:        MULtiply                                                */
 | 
| -  /* Opcode range: 0x63                                                    */
 | 
| -  /* Stack:        f26.6 f26.6 --> f26.6                                   */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_MUL( INS_ARG )
 | 
| -  {
 | 
| -    DO_MUL
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ABS[]:        ABSolute value                                          */
 | 
| -  /* Opcode range: 0x64                                                    */
 | 
| -  /* Stack:        f26.6 --> f26.6                                         */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ABS( INS_ARG )
 | 
| -  {
 | 
| -    DO_ABS
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* NEG[]:        NEGate                                                  */
 | 
| -  /* Opcode range: 0x65                                                    */
 | 
| -  /* Stack: f26.6 --> f26.6                                                */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_NEG( INS_ARG )
 | 
| -  {
 | 
| -    DO_NEG
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* FLOOR[]:      FLOOR                                                   */
 | 
| -  /* Opcode range: 0x66                                                    */
 | 
| -  /* Stack:        f26.6 --> f26.6                                         */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_FLOOR( INS_ARG )
 | 
| -  {
 | 
| -    DO_FLOOR
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* CEILING[]:    CEILING                                                 */
 | 
| -  /* Opcode range: 0x67                                                    */
 | 
| -  /* Stack:        f26.6 --> f26.6                                         */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_CEILING( INS_ARG )
 | 
| -  {
 | 
| -    DO_CEILING
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* RS[]:         Read Store                                              */
 | 
| -  /* Opcode range: 0x43                                                    */
 | 
| -  /* Stack:        uint32 --> uint32                                       */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_RS( INS_ARG )
 | 
| -  {
 | 
| -    DO_RS
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* WS[]:         Write Store                                             */
 | 
| -  /* Opcode range: 0x42                                                    */
 | 
| -  /* Stack:        uint32 uint32 -->                                       */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_WS( INS_ARG )
 | 
| -  {
 | 
| -    DO_WS
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* WCVTP[]:      Write CVT in Pixel units                                */
 | 
| -  /* Opcode range: 0x44                                                    */
 | 
| -  /* Stack:        f26.6 uint32 -->                                        */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_WCVTP( INS_ARG )
 | 
| -  {
 | 
| -    DO_WCVTP
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* WCVTF[]:      Write CVT in Funits                                     */
 | 
| -  /* Opcode range: 0x70                                                    */
 | 
| -  /* Stack:        uint32 uint32 -->                                       */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_WCVTF( INS_ARG )
 | 
| -  {
 | 
| -    DO_WCVTF
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* RCVT[]:       Read CVT                                                */
 | 
| -  /* Opcode range: 0x45                                                    */
 | 
| -  /* Stack:        uint32 --> f26.6                                        */
 | 
| +  /* FDEF[]:       Function DEFinition                                     */
 | 
| +  /* Opcode range: 0x2C                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_RCVT( INS_ARG )
 | 
| +  Ins_FDEF( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    DO_RCVT
 | 
| -  }
 | 
| +    FT_ULong       n;
 | 
| +    TT_DefRecord*  rec;
 | 
| +    TT_DefRecord*  limit;
 | 
|  
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    /* arguments to opcodes are skipped by `SKIP_Code' */
 | 
| +    FT_Byte    opcode_pattern[9][12] = {
 | 
| +                 /* #0 inline delta function 1 */
 | 
| +                 {
 | 
| +                   0x4B, /* PPEM    */
 | 
| +                   0x53, /* GTEQ    */
 | 
| +                   0x23, /* SWAP    */
 | 
| +                   0x4B, /* PPEM    */
 | 
| +                   0x51, /* LTEQ    */
 | 
| +                   0x5A, /* AND     */
 | 
| +                   0x58, /* IF      */
 | 
| +                   0x38, /*   SHPIX */
 | 
| +                   0x1B, /* ELSE    */
 | 
| +                   0x21, /*   POP   */
 | 
| +                   0x21, /*   POP   */
 | 
| +                   0x59  /* EIF     */
 | 
| +                 },
 | 
| +                 /* #1 inline delta function 2 */
 | 
| +                 {
 | 
| +                   0x4B, /* PPEM    */
 | 
| +                   0x54, /* EQ      */
 | 
| +                   0x58, /* IF      */
 | 
| +                   0x38, /*   SHPIX */
 | 
| +                   0x1B, /* ELSE    */
 | 
| +                   0x21, /*   POP   */
 | 
| +                   0x21, /*   POP   */
 | 
| +                   0x59  /* EIF     */
 | 
| +                 },
 | 
| +                 /* #2 diagonal stroke function */
 | 
| +                 {
 | 
| +                   0x20, /* DUP     */
 | 
| +                   0x20, /* DUP     */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   1     */
 | 
| +                   0x60, /* ADD     */
 | 
| +                   0x46, /* GC_cur  */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   64    */
 | 
| +                   0x23, /* SWAP    */
 | 
| +                   0x42  /* WS      */
 | 
| +                 },
 | 
| +                 /* #3 VacuFormRound function */
 | 
| +                 {
 | 
| +                   0x45, /* RCVT    */
 | 
| +                   0x23, /* SWAP    */
 | 
| +                   0x46, /* GC_cur  */
 | 
| +                   0x60, /* ADD     */
 | 
| +                   0x20, /* DUP     */
 | 
| +                   0xB0  /* PUSHB_1 */
 | 
| +                         /*   38    */
 | 
| +                 },
 | 
| +                 /* #4 TTFautohint bytecode (old) */
 | 
| +                 {
 | 
| +                   0x20, /* DUP     */
 | 
| +                   0x64, /* ABS     */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   32    */
 | 
| +                   0x60, /* ADD     */
 | 
| +                   0x66, /* FLOOR   */
 | 
| +                   0x23, /* SWAP    */
 | 
| +                   0xB0  /* PUSHB_1 */
 | 
| +                 },
 | 
| +                 /* #5 spacing function 1 */
 | 
| +                 {
 | 
| +                   0x01, /* SVTCA_x */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   24    */
 | 
| +                   0x43, /* RS      */
 | 
| +                   0x58  /* IF      */
 | 
| +                 },
 | 
| +                 /* #6 spacing function 2 */
 | 
| +                 {
 | 
| +                   0x01, /* SVTCA_x */
 | 
| +                   0x18, /* RTG     */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   24    */
 | 
| +                   0x43, /* RS      */
 | 
| +                   0x58  /* IF      */
 | 
| +                 },
 | 
| +                 /* #7 TypeMan Talk DiagEndCtrl function */
 | 
| +                 {
 | 
| +                   0x01, /* SVTCA_x */
 | 
| +                   0x20, /* DUP     */
 | 
| +                   0xB0, /* PUSHB_1 */
 | 
| +                         /*   3     */
 | 
| +                   0x25, /* CINDEX  */
 | 
| +                 },
 | 
| +                 /* #8 TypeMan Talk Align */
 | 
| +                 {
 | 
| +                   0x06, /* SPVTL   */
 | 
| +                   0x7D, /* RDTG    */
 | 
| +                 },
 | 
| +               };
 | 
| +    FT_UShort  opcode_patterns   = 9;
 | 
| +    FT_UShort  opcode_pointer[9] = {  0, 0, 0, 0, 0, 0, 0, 0, 0 };
 | 
| +    FT_UShort  opcode_size[9]    = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
 | 
| +    FT_UShort  i;
 | 
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* AA[]:         Adjust Angle                                            */
 | 
| -  /* Opcode range: 0x7F                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_AA( INS_ARG )
 | 
| -  {
 | 
| -    /* intentionally no longer supported */
 | 
| -  }
 | 
|  
 | 
| +    /* some font programs are broken enough to redefine functions! */
 | 
| +    /* We will then parse the current table.                       */
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* DEBUG[]:      DEBUG.  Unsupported.                                    */
 | 
| -  /* Opcode range: 0x4F                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| -  /*                                                                       */
 | 
| -  /* Note: The original instruction pops a value from the stack.           */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_DEBUG( INS_ARG )
 | 
| -  {
 | 
| -    DO_DEBUG
 | 
| -  }
 | 
| +    rec   = exc->FDefs;
 | 
| +    limit = rec + exc->numFDefs;
 | 
| +    n     = (FT_ULong)args[0];
 | 
|  
 | 
| +    for ( ; rec < limit; rec++ )
 | 
| +    {
 | 
| +      if ( rec->opc == n )
 | 
| +        break;
 | 
| +    }
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ROUND[ab]:    ROUND value                                             */
 | 
| -  /* Opcode range: 0x68-0x6B                                               */
 | 
| -  /* Stack:        f26.6 --> f26.6                                         */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ROUND( INS_ARG )
 | 
| -  {
 | 
| -    DO_ROUND
 | 
| -  }
 | 
| +    if ( rec == limit )
 | 
| +    {
 | 
| +      /* check that there is enough room for new functions */
 | 
| +      if ( exc->numFDefs >= exc->maxFDefs )
 | 
| +      {
 | 
| +        exc->error = FT_THROW( Too_Many_Function_Defs );
 | 
| +        return;
 | 
| +      }
 | 
| +      exc->numFDefs++;
 | 
| +    }
 | 
|  
 | 
| +    /* Although FDEF takes unsigned 32-bit integer,  */
 | 
| +    /* func # must be within unsigned 16-bit integer */
 | 
| +    if ( n > 0xFFFFU )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Too_Many_Function_Defs );
 | 
| +      return;
 | 
| +    }
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* NROUND[ab]:   No ROUNDing of value                                    */
 | 
| -  /* Opcode range: 0x6C-0x6F                                               */
 | 
| -  /* Stack:        f26.6 --> f26.6                                         */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_NROUND( INS_ARG )
 | 
| -  {
 | 
| -    DO_NROUND
 | 
| -  }
 | 
| +    rec->range          = exc->curRange;
 | 
| +    rec->opc            = (FT_UInt16)n;
 | 
| +    rec->start          = exc->IP + 1;
 | 
| +    rec->active         = TRUE;
 | 
| +    rec->inline_delta   = FALSE;
 | 
| +    rec->sph_fdef_flags = 0x0000;
 | 
|  
 | 
| +    if ( n > exc->maxFunc )
 | 
| +      exc->maxFunc = (FT_UInt16)n;
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* MAX[]:        MAXimum                                                 */
 | 
| -  /* Opcode range: 0x68                                                    */
 | 
| -  /* Stack:        int32? int32? --> int32                                 */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_MAX( INS_ARG )
 | 
| -  {
 | 
| -    DO_MAX
 | 
| -  }
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    /* We don't know for sure these are typeman functions, */
 | 
| +    /* however they are only active when RS 22 is called   */
 | 
| +    if ( n >= 64 && n <= 66 )
 | 
| +      rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
 | 
| +#endif
 | 
|  
 | 
| +    /* Now skip the whole function definition. */
 | 
| +    /* We don't allow nested IDEFS & FDEFs.    */
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* MIN[]:        MINimum                                                 */
 | 
| -  /* Opcode range: 0x69                                                    */
 | 
| -  /* Stack:        int32? int32? --> int32                                 */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_MIN( INS_ARG )
 | 
| -  {
 | 
| -    DO_MIN
 | 
| -  }
 | 
| +    while ( SkipCode( exc ) == SUCCESS )
 | 
| +    {
 | 
|  
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|  
 | 
| -#endif  /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
 | 
| +      if ( SUBPIXEL_HINTING )
 | 
| +      {
 | 
| +        for ( i = 0; i < opcode_patterns; i++ )
 | 
| +        {
 | 
| +          if ( opcode_pointer[i] < opcode_size[i]                  &&
 | 
| +               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
 | 
| +          {
 | 
| +            opcode_pointer[i] += 1;
 | 
|  
 | 
| +            if ( opcode_pointer[i] == opcode_size[i] )
 | 
| +            {
 | 
| +              FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
 | 
| +                          i, n,
 | 
| +                          exc->face->root.family_name,
 | 
| +                          exc->face->root.style_name ));
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* The following functions are called as is within the switch statement. */
 | 
| -  /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| +              switch ( i )
 | 
| +              {
 | 
| +              case 0:
 | 
| +                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_1;
 | 
| +                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
 | 
| +                break;
 | 
|  
 | 
| +              case 1:
 | 
| +                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_2;
 | 
| +                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
 | 
| +                break;
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* MINDEX[]:     Move INDEXed element                                    */
 | 
| -  /* Opcode range: 0x26                                                    */
 | 
| -  /* Stack:        int32? --> StkElt                                       */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_MINDEX( INS_ARG )
 | 
| -  {
 | 
| -    FT_Long  L, K;
 | 
| +              case 2:
 | 
| +                switch ( n )
 | 
| +                {
 | 
| +                  /* needs to be implemented still */
 | 
| +                case 58:
 | 
| +                  rec->sph_fdef_flags             |= SPH_FDEF_DIAGONAL_STROKE;
 | 
| +                  exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
 | 
| +                }
 | 
| +                break;
 | 
|  
 | 
| +              case 3:
 | 
| +                switch ( n )
 | 
| +                {
 | 
| +                case 0:
 | 
| +                  rec->sph_fdef_flags             |= SPH_FDEF_VACUFORM_ROUND_1;
 | 
| +                  exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
 | 
| +                }
 | 
| +                break;
 | 
|  
 | 
| -    L = args[0];
 | 
| +              case 4:
 | 
| +                /* probably not necessary to detect anymore */
 | 
| +                rec->sph_fdef_flags             |= SPH_FDEF_TTFAUTOHINT_1;
 | 
| +                exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
 | 
| +                break;
 | 
|  
 | 
| -    if ( L <= 0 || L > CUR.args )
 | 
| -    {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| -    }
 | 
| -    else
 | 
| -    {
 | 
| -      K = CUR.stack[CUR.args - L];
 | 
| +              case 5:
 | 
| +                switch ( n )
 | 
| +                {
 | 
| +                case 0:
 | 
| +                case 1:
 | 
| +                case 2:
 | 
| +                case 4:
 | 
| +                case 7:
 | 
| +                case 8:
 | 
| +                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_1;
 | 
| +                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
 | 
| +                }
 | 
| +                break;
 | 
|  
 | 
| -      FT_ARRAY_MOVE( &CUR.stack[CUR.args - L    ],
 | 
| -                     &CUR.stack[CUR.args - L + 1],
 | 
| -                     ( L - 1 ) );
 | 
| +              case 6:
 | 
| +                switch ( n )
 | 
| +                {
 | 
| +                case 0:
 | 
| +                case 1:
 | 
| +                case 2:
 | 
| +                case 4:
 | 
| +                case 7:
 | 
| +                case 8:
 | 
| +                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_2;
 | 
| +                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
 | 
| +                }
 | 
| +                break;
 | 
|  
 | 
| -      CUR.stack[CUR.args - 1] = K;
 | 
| -    }
 | 
| -  }
 | 
| +               case 7:
 | 
| +                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| +                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| +                 break;
 | 
|  
 | 
| +               case 8:
 | 
| +#if 0
 | 
| +                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| +                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| +#endif
 | 
| +                 break;
 | 
| +              }
 | 
| +              opcode_pointer[i] = 0;
 | 
| +            }
 | 
| +          }
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ROLL[]:       ROLL top three elements                                 */
 | 
| -  /* Opcode range: 0x8A                                                    */
 | 
| -  /* Stack:        3 * StkElt --> 3 * StkElt                               */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ROLL( INS_ARG )
 | 
| -  {
 | 
| -    FT_Long  A, B, C;
 | 
| +          else
 | 
| +            opcode_pointer[i] = 0;
 | 
| +        }
 | 
|  
 | 
| -    FT_UNUSED_EXEC;
 | 
| +        /* Set sph_compatibility_mode only when deltas are detected */
 | 
| +        exc->face->sph_compatibility_mode =
 | 
| +          ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
 | 
| +            ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
 | 
| +      }
 | 
|  
 | 
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    A = args[2];
 | 
| -    B = args[1];
 | 
| -    C = args[0];
 | 
| +      switch ( exc->opcode )
 | 
| +      {
 | 
| +      case 0x89:    /* IDEF */
 | 
| +      case 0x2C:    /* FDEF */
 | 
| +        exc->error = FT_THROW( Nested_DEFS );
 | 
| +        return;
 | 
|  
 | 
| -    args[2] = C;
 | 
| -    args[1] = A;
 | 
| -    args[0] = B;
 | 
| +      case 0x2D:   /* ENDF */
 | 
| +        rec->end = exc->IP;
 | 
| +        return;
 | 
| +      }
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* MANAGING THE FLOW OF CONTROL                                          */
 | 
| -  /*                                                                       */
 | 
| -  /*   Instructions appear in the specification's order.                   */
 | 
| +  /* ENDF[]:       END Function definition                                 */
 | 
| +  /* Opcode range: 0x2D                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| +  static void
 | 
| +  Ins_ENDF( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    TT_CallRec*  pRec;
 | 
|  
 | 
|  
 | 
| -  static FT_Bool
 | 
| -  SkipCode( EXEC_OP )
 | 
| -  {
 | 
| -    CUR.IP += CUR.length;
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    exc->sph_in_func_flags = 0x0000;
 | 
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    if ( CUR.IP < CUR.codeSize )
 | 
| +    if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
 | 
|      {
 | 
| -      CUR.opcode = CUR.code[CUR.IP];
 | 
| +      exc->error = FT_THROW( ENDF_In_Exec_Stream );
 | 
| +      return;
 | 
| +    }
 | 
|  
 | 
| -      CUR.length = opcode_length[CUR.opcode];
 | 
| -      if ( CUR.length < 0 )
 | 
| -      {
 | 
| -        if ( CUR.IP + 1 >= CUR.codeSize )
 | 
| -          goto Fail_Overflow;
 | 
| -        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
 | 
| -      }
 | 
| +    exc->callTop--;
 | 
|  
 | 
| -      if ( CUR.IP + CUR.length <= CUR.codeSize )
 | 
| -        return SUCCESS;
 | 
| +    pRec = &exc->callStack[exc->callTop];
 | 
| +
 | 
| +    pRec->Cur_Count--;
 | 
| +
 | 
| +    exc->step_ins = FALSE;
 | 
| +
 | 
| +    if ( pRec->Cur_Count > 0 )
 | 
| +    {
 | 
| +      exc->callTop++;
 | 
| +      exc->IP = pRec->Def->start;
 | 
|      }
 | 
| +    else
 | 
| +      /* Loop through the current function */
 | 
| +      Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP );
 | 
|  
 | 
| -  Fail_Overflow:
 | 
| -    CUR.error = FT_THROW( Code_Overflow );
 | 
| -    return FAILURE;
 | 
| +    /* Exit the current call frame.                      */
 | 
| +
 | 
| +    /* NOTE: If the last instruction of a program is a   */
 | 
| +    /*       CALL or LOOPCALL, the return address is     */
 | 
| +    /*       always out of the code range.  This is a    */
 | 
| +    /*       valid address, and it is why we do not test */
 | 
| +    /*       the result of Ins_Goto_CodeRange() here!    */
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* IF[]:         IF test                                                 */
 | 
| -  /* Opcode range: 0x58                                                    */
 | 
| -  /* Stack:        StkElt -->                                              */
 | 
| +  /* CALL[]:       CALL function                                           */
 | 
| +  /* Opcode range: 0x2B                                                    */
 | 
| +  /* Stack:        uint32? -->                                             */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_IF( INS_ARG )
 | 
| +  Ins_CALL( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
| -    FT_Int   nIfs;
 | 
| -    FT_Bool  Out;
 | 
| +    FT_ULong       F;
 | 
| +    TT_CallRec*    pCrec;
 | 
| +    TT_DefRecord*  def;
 | 
|  
 | 
|  
 | 
| -    if ( args[0] != 0 )
 | 
| -      return;
 | 
| +    /* first of all, check the index */
 | 
|  
 | 
| -    nIfs = 1;
 | 
| -    Out = 0;
 | 
| +    F = (FT_ULong)args[0];
 | 
| +    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
 | 
| +      goto Fail;
 | 
|  
 | 
| -    do
 | 
| +    /* Except for some old Apple fonts, all functions in a TrueType */
 | 
| +    /* font are defined in increasing order, starting from 0.  This */
 | 
| +    /* means that we normally have                                  */
 | 
| +    /*                                                              */
 | 
| +    /*    exc->maxFunc+1 == exc->numFDefs                           */
 | 
| +    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
 | 
| +    /*                                                              */
 | 
| +    /* If this isn't true, we need to look up the function table.   */
 | 
| +
 | 
| +    def = exc->FDefs + F;
 | 
| +    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
 | 
|      {
 | 
| -      if ( SKIP_Code() == FAILURE )
 | 
| -        return;
 | 
| +      /* look up the FDefs table */
 | 
| +      TT_DefRecord*  limit;
 | 
|  
 | 
| -      switch ( CUR.opcode )
 | 
| -      {
 | 
| -      case 0x58:      /* IF */
 | 
| -        nIfs++;
 | 
| -        break;
 | 
|  
 | 
| -      case 0x1B:      /* ELSE */
 | 
| -        Out = FT_BOOL( nIfs == 1 );
 | 
| -        break;
 | 
| +      def   = exc->FDefs;
 | 
| +      limit = def + exc->numFDefs;
 | 
|  
 | 
| -      case 0x59:      /* EIF */
 | 
| -        nIfs--;
 | 
| -        Out = FT_BOOL( nIfs == 0 );
 | 
| -        break;
 | 
| -      }
 | 
| -    } while ( Out == 0 );
 | 
| -  }
 | 
| +      while ( def < limit && def->opc != F )
 | 
| +        def++;
 | 
|  
 | 
| +      if ( def == limit )
 | 
| +        goto Fail;
 | 
| +    }
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* ELSE[]:       ELSE                                                    */
 | 
| -  /* Opcode range: 0x1B                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| -  /*                                                                       */
 | 
| -  static void
 | 
| -  Ins_ELSE( INS_ARG )
 | 
| -  {
 | 
| -    FT_Int  nIfs;
 | 
| +    /* check that the function is active */
 | 
| +    if ( !def->active )
 | 
| +      goto Fail;
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    if ( SUBPIXEL_HINTING                                               &&
 | 
| +         exc->ignore_x_mode                                             &&
 | 
| +         ( ( exc->iup_called                                        &&
 | 
| +             ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
 | 
| +           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )        ) )
 | 
| +      goto Fail;
 | 
| +    else
 | 
| +      exc->sph_in_func_flags = def->sph_fdef_flags;
 | 
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| +    /* check the call stack */
 | 
| +    if ( exc->callTop >= exc->callSize )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
| +    }
 | 
|  
 | 
| -    nIfs = 1;
 | 
| +    pCrec = exc->callStack + exc->callTop;
 | 
|  
 | 
| -    do
 | 
| -    {
 | 
| -      if ( SKIP_Code() == FAILURE )
 | 
| -        return;
 | 
| +    pCrec->Caller_Range = exc->curRange;
 | 
| +    pCrec->Caller_IP    = exc->IP + 1;
 | 
| +    pCrec->Cur_Count    = 1;
 | 
| +    pCrec->Def          = def;
 | 
|  
 | 
| -      switch ( CUR.opcode )
 | 
| -      {
 | 
| -      case 0x58:    /* IF */
 | 
| -        nIfs++;
 | 
| -        break;
 | 
| +    exc->callTop++;
 | 
|  
 | 
| -      case 0x59:    /* EIF */
 | 
| -        nIfs--;
 | 
| -        break;
 | 
| -      }
 | 
| -    } while ( nIfs != 0 );
 | 
| -  }
 | 
| +    Ins_Goto_CodeRange( exc, def->range, def->start );
 | 
|  
 | 
| +    exc->step_ins = FALSE;
 | 
|  
 | 
| -  /*************************************************************************/
 | 
| -  /*                                                                       */
 | 
| -  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
 | 
| -  /*                                                                       */
 | 
| -  /*   Instructions appear in the specification's order.                   */
 | 
| -  /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| +    return;
 | 
| +
 | 
| +  Fail:
 | 
| +    exc->error = FT_THROW( Invalid_Reference );
 | 
| +  }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* FDEF[]:       Function DEFinition                                     */
 | 
| -  /* Opcode range: 0x2C                                                    */
 | 
| -  /* Stack:        uint32 -->                                              */
 | 
| +  /* LOOPCALL[]:   LOOP and CALL function                                  */
 | 
| +  /* Opcode range: 0x2A                                                    */
 | 
| +  /* Stack:        uint32? Eint16? -->                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FDEF( INS_ARG )
 | 
| +  Ins_LOOPCALL( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
| -    FT_ULong       n;
 | 
| -    TT_DefRecord*  rec;
 | 
| -    TT_DefRecord*  limit;
 | 
| +    FT_ULong       F;
 | 
| +    TT_CallRec*    pCrec;
 | 
| +    TT_DefRecord*  def;
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    /* arguments to opcodes are skipped by `SKIP_Code' */
 | 
| -    FT_Byte    opcode_pattern[9][12] = {
 | 
| -                 /* #0 inline delta function 1 */
 | 
| -                 {
 | 
| -                   0x4B, /* PPEM    */
 | 
| -                   0x53, /* GTEQ    */
 | 
| -                   0x23, /* SWAP    */
 | 
| -                   0x4B, /* PPEM    */
 | 
| -                   0x51, /* LTEQ    */
 | 
| -                   0x5A, /* AND     */
 | 
| -                   0x58, /* IF      */
 | 
| -                   0x38, /*   SHPIX */
 | 
| -                   0x1B, /* ELSE    */
 | 
| -                   0x21, /*   POP   */
 | 
| -                   0x21, /*   POP   */
 | 
| -                   0x59  /* EIF     */
 | 
| -                 },
 | 
| -                 /* #1 inline delta function 2 */
 | 
| -                 {
 | 
| -                   0x4B, /* PPEM    */
 | 
| -                   0x54, /* EQ      */
 | 
| -                   0x58, /* IF      */
 | 
| -                   0x38, /*   SHPIX */
 | 
| -                   0x1B, /* ELSE    */
 | 
| -                   0x21, /*   POP   */
 | 
| -                   0x21, /*   POP   */
 | 
| -                   0x59  /* EIF     */
 | 
| -                 },
 | 
| -                 /* #2 diagonal stroke function */
 | 
| -                 {
 | 
| -                   0x20, /* DUP     */
 | 
| -                   0x20, /* DUP     */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   1     */
 | 
| -                   0x60, /* ADD     */
 | 
| -                   0x46, /* GC_cur  */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   64    */
 | 
| -                   0x23, /* SWAP    */
 | 
| -                   0x42  /* WS      */
 | 
| -                 },
 | 
| -                 /* #3 VacuFormRound function */
 | 
| -                 {
 | 
| -                   0x45, /* RCVT    */
 | 
| -                   0x23, /* SWAP    */
 | 
| -                   0x46, /* GC_cur  */
 | 
| -                   0x60, /* ADD     */
 | 
| -                   0x20, /* DUP     */
 | 
| -                   0xB0  /* PUSHB_1 */
 | 
| -                         /*   38    */
 | 
| -                 },
 | 
| -                 /* #4 TTFautohint bytecode (old) */
 | 
| -                 {
 | 
| -                   0x20, /* DUP     */
 | 
| -                   0x64, /* ABS     */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   32    */
 | 
| -                   0x60, /* ADD     */
 | 
| -                   0x66, /* FLOOR   */
 | 
| -                   0x23, /* SWAP    */
 | 
| -                   0xB0  /* PUSHB_1 */
 | 
| -                 },
 | 
| -                 /* #5 spacing function 1 */
 | 
| -                 {
 | 
| -                   0x01, /* SVTCA_x */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   24    */
 | 
| -                   0x43, /* RS      */
 | 
| -                   0x58  /* IF      */
 | 
| -                 },
 | 
| -                 /* #6 spacing function 2 */
 | 
| -                 {
 | 
| -                   0x01, /* SVTCA_x */
 | 
| -                   0x18, /* RTG     */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   24    */
 | 
| -                   0x43, /* RS      */
 | 
| -                   0x58  /* IF      */
 | 
| -                 },
 | 
| -                 /* #7 TypeMan Talk DiagEndCtrl function */
 | 
| -                 {
 | 
| -                   0x01, /* SVTCA_x */
 | 
| -                   0x20, /* DUP     */
 | 
| -                   0xB0, /* PUSHB_1 */
 | 
| -                         /*   3     */
 | 
| -                   0x25, /* CINDEX  */
 | 
| -                 },
 | 
| -                 /* #8 TypeMan Talk Align */
 | 
| -                 {
 | 
| -                   0x06, /* SPVTL   */
 | 
| -                   0x7D, /* RDTG    */
 | 
| -                 },
 | 
| -               };
 | 
| -    FT_UShort  opcode_patterns   = 9;
 | 
| -    FT_UShort  opcode_pointer[9] = {  0, 0, 0, 0, 0, 0, 0, 0, 0 };
 | 
| -    FT_UShort  opcode_size[9]    = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
 | 
| -    FT_UShort  i;
 | 
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| +
 | 
| +    /* first of all, check the index */
 | 
| +    F = (FT_ULong)args[1];
 | 
| +    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
 | 
| +      goto Fail;
 | 
| +
 | 
| +    /* Except for some old Apple fonts, all functions in a TrueType */
 | 
| +    /* font are defined in increasing order, starting from 0.  This */
 | 
| +    /* means that we normally have                                  */
 | 
| +    /*                                                              */
 | 
| +    /*    exc->maxFunc+1 == exc->numFDefs                           */
 | 
| +    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
 | 
| +    /*                                                              */
 | 
| +    /* If this isn't true, we need to look up the function table.   */
 | 
| +
 | 
| +    def = exc->FDefs + F;
 | 
| +    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
 | 
| +    {
 | 
| +      /* look up the FDefs table */
 | 
| +      TT_DefRecord*  limit;
 | 
|  
 | 
|  
 | 
| -    /* some font programs are broken enough to redefine functions! */
 | 
| -    /* We will then parse the current table.                       */
 | 
| +      def   = exc->FDefs;
 | 
| +      limit = def + exc->numFDefs;
 | 
|  
 | 
| -    rec   = CUR.FDefs;
 | 
| -    limit = rec + CUR.numFDefs;
 | 
| -    n     = args[0];
 | 
| +      while ( def < limit && def->opc != F )
 | 
| +        def++;
 | 
|  
 | 
| -    for ( ; rec < limit; rec++ )
 | 
| +      if ( def == limit )
 | 
| +        goto Fail;
 | 
| +    }
 | 
| +
 | 
| +    /* check that the function is active */
 | 
| +    if ( !def->active )
 | 
| +      goto Fail;
 | 
| +
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    if ( SUBPIXEL_HINTING                                    &&
 | 
| +         exc->ignore_x_mode                                  &&
 | 
| +         ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
 | 
| +      goto Fail;
 | 
| +    else
 | 
| +      exc->sph_in_func_flags = def->sph_fdef_flags;
 | 
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| +
 | 
| +    /* check stack */
 | 
| +    if ( exc->callTop >= exc->callSize )
 | 
|      {
 | 
| -      if ( rec->opc == n )
 | 
| -        break;
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
|      }
 | 
|  
 | 
| -    if ( rec == limit )
 | 
| +    if ( args[0] > 0 )
 | 
|      {
 | 
| -      /* check that there is enough room for new functions */
 | 
| -      if ( CUR.numFDefs >= CUR.maxFDefs )
 | 
| +      pCrec = exc->callStack + exc->callTop;
 | 
| +
 | 
| +      pCrec->Caller_Range = exc->curRange;
 | 
| +      pCrec->Caller_IP    = exc->IP + 1;
 | 
| +      pCrec->Cur_Count    = (FT_Int)args[0];
 | 
| +      pCrec->Def          = def;
 | 
| +
 | 
| +      exc->callTop++;
 | 
| +
 | 
| +      Ins_Goto_CodeRange( exc, def->range, def->start );
 | 
| +
 | 
| +      exc->step_ins = FALSE;
 | 
| +    }
 | 
| +
 | 
| +    return;
 | 
| +
 | 
| +  Fail:
 | 
| +    exc->error = FT_THROW( Invalid_Reference );
 | 
| +  }
 | 
| +
 | 
| +
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* IDEF[]:       Instruction DEFinition                                  */
 | 
| +  /* Opcode range: 0x89                                                    */
 | 
| +  /* Stack:        Eint8 -->                                               */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_IDEF( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
| +  {
 | 
| +    TT_DefRecord*  def;
 | 
| +    TT_DefRecord*  limit;
 | 
| +
 | 
| +
 | 
| +    /*  First of all, look for the same function in our table */
 | 
| +
 | 
| +    def   = exc->IDefs;
 | 
| +    limit = def + exc->numIDefs;
 | 
| +
 | 
| +    for ( ; def < limit; def++ )
 | 
| +      if ( def->opc == (FT_ULong)args[0] )
 | 
| +        break;
 | 
| +
 | 
| +    if ( def == limit )
 | 
| +    {
 | 
| +      /* check that there is enough room for a new instruction */
 | 
| +      if ( exc->numIDefs >= exc->maxIDefs )
 | 
|        {
 | 
| -        CUR.error = FT_THROW( Too_Many_Function_Defs );
 | 
| +        exc->error = FT_THROW( Too_Many_Instruction_Defs );
 | 
|          return;
 | 
|        }
 | 
| -      CUR.numFDefs++;
 | 
| +      exc->numIDefs++;
 | 
|      }
 | 
|  
 | 
| -    /* Although FDEF takes unsigned 32-bit integer,  */
 | 
| -    /* func # must be within unsigned 16-bit integer */
 | 
| -    if ( n > 0xFFFFU )
 | 
| +    /* opcode must be unsigned 8-bit integer */
 | 
| +    if ( 0 > args[0] || args[0] > 0x00FF )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Too_Many_Function_Defs );
 | 
| +      exc->error = FT_THROW( Too_Many_Instruction_Defs );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    rec->range          = CUR.curRange;
 | 
| -    rec->opc            = (FT_UInt16)n;
 | 
| -    rec->start          = CUR.IP + 1;
 | 
| -    rec->active         = TRUE;
 | 
| -    rec->inline_delta   = FALSE;
 | 
| -    rec->sph_fdef_flags = 0x0000;
 | 
| -
 | 
| -    if ( n > CUR.maxFunc )
 | 
| -      CUR.maxFunc = (FT_UInt16)n;
 | 
| +    def->opc    = (FT_Byte)args[0];
 | 
| +    def->start  = exc->IP + 1;
 | 
| +    def->range  = exc->curRange;
 | 
| +    def->active = TRUE;
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    /* We don't know for sure these are typeman functions, */
 | 
| -    /* however they are only active when RS 22 is called   */
 | 
| -    if ( n >= 64 && n <= 66 )
 | 
| -      rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
 | 
| -#endif
 | 
| +    if ( (FT_ULong)args[0] > exc->maxIns )
 | 
| +      exc->maxIns = (FT_Byte)args[0];
 | 
|  
 | 
|      /* Now skip the whole function definition. */
 | 
| -    /* We don't allow nested IDEFS & FDEFs.    */
 | 
| +    /* We don't allow nested IDEFs & FDEFs.    */
 | 
|  
 | 
| -    while ( SKIP_Code() == SUCCESS )
 | 
| +    while ( SkipCode( exc ) == SUCCESS )
 | 
|      {
 | 
| +      switch ( exc->opcode )
 | 
| +      {
 | 
| +      case 0x89:   /* IDEF */
 | 
| +      case 0x2C:   /* FDEF */
 | 
| +        exc->error = FT_THROW( Nested_DEFS );
 | 
| +        return;
 | 
| +      case 0x2D:   /* ENDF */
 | 
| +        return;
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|  
 | 
| -      if ( SUBPIXEL_HINTING )
 | 
| -      {
 | 
| -        for ( i = 0; i < opcode_patterns; i++ )
 | 
| -        {
 | 
| -          if ( opcode_pointer[i] < opcode_size[i]                 &&
 | 
| -               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
 | 
| -          {
 | 
| -            opcode_pointer[i] += 1;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* PUSHING DATA ONTO THE INTERPRETER STACK                               */
 | 
| +  /*                                                                       */
 | 
| +  /*************************************************************************/
 | 
|  
 | 
| -            if ( opcode_pointer[i] == opcode_size[i] )
 | 
| -            {
 | 
| -              FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
 | 
| -                          i, n,
 | 
| -                          CUR.face->root.family_name,
 | 
| -                          CUR.face->root.style_name ));
 | 
|  
 | 
| -              switch ( i )
 | 
| -              {
 | 
| -              case 0:
 | 
| -                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_1;
 | 
| -                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
 | 
| -                break;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* NPUSHB[]:     PUSH N Bytes                                            */
 | 
| +  /* Opcode range: 0x40                                                    */
 | 
| +  /* Stack:        --> uint32...                                           */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_NPUSHB( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
| +  {
 | 
| +    FT_UShort  L, K;
 | 
|  
 | 
| -              case 1:
 | 
| -                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_2;
 | 
| -                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
 | 
| -                break;
 | 
|  
 | 
| -              case 2:
 | 
| -                switch ( n )
 | 
| -                {
 | 
| -                  /* needs to be implemented still */
 | 
| -                case 58:
 | 
| -                  rec->sph_fdef_flags            |= SPH_FDEF_DIAGONAL_STROKE;
 | 
| -                  CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
 | 
| -                }
 | 
| -                break;
 | 
| +    L = (FT_UShort)exc->code[exc->IP + 1];
 | 
|  
 | 
| -              case 3:
 | 
| -                switch ( n )
 | 
| -                {
 | 
| -                case 0:
 | 
| -                  rec->sph_fdef_flags            |= SPH_FDEF_VACUFORM_ROUND_1;
 | 
| -                  CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
 | 
| -                }
 | 
| -                break;
 | 
| +    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
| +    }
 | 
|  
 | 
| -              case 4:
 | 
| -                /* probably not necessary to detect anymore */
 | 
| -                rec->sph_fdef_flags            |= SPH_FDEF_TTFAUTOHINT_1;
 | 
| -                CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
 | 
| -                break;
 | 
| +    for ( K = 1; K <= L; K++ )
 | 
| +      args[K - 1] = exc->code[exc->IP + K + 1];
 | 
|  
 | 
| -              case 5:
 | 
| -                switch ( n )
 | 
| -                {
 | 
| -                case 0:
 | 
| -                case 1:
 | 
| -                case 2:
 | 
| -                case 4:
 | 
| -                case 7:
 | 
| -                case 8:
 | 
| -                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_1;
 | 
| -                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
 | 
| -                }
 | 
| -                break;
 | 
| +    exc->new_top += L;
 | 
| +  }
 | 
|  
 | 
| -              case 6:
 | 
| -                switch ( n )
 | 
| -                {
 | 
| -                case 0:
 | 
| -                case 1:
 | 
| -                case 2:
 | 
| -                case 4:
 | 
| -                case 7:
 | 
| -                case 8:
 | 
| -                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_2;
 | 
| -                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
 | 
| -                }
 | 
| -                break;
 | 
|  
 | 
| -               case 7:
 | 
| -                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| -                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| -                 break;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* NPUSHW[]:     PUSH N Words                                            */
 | 
| +  /* Opcode range: 0x41                                                    */
 | 
| +  /* Stack:        --> int32...                                            */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_NPUSHW( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
| +  {
 | 
| +    FT_UShort  L, K;
 | 
|  
 | 
| -               case 8:
 | 
| -#if 0
 | 
| -                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| -                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 | 
| -#endif
 | 
| -                 break;
 | 
| -              }
 | 
| -              opcode_pointer[i] = 0;
 | 
| -            }
 | 
| -          }
 | 
|  
 | 
| -          else
 | 
| -            opcode_pointer[i] = 0;
 | 
| -        }
 | 
| +    L = (FT_UShort)exc->code[exc->IP + 1];
 | 
|  
 | 
| -        /* Set sph_compatibility_mode only when deltas are detected */
 | 
| -        CUR.face->sph_compatibility_mode =
 | 
| -          ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
 | 
| -            ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
 | 
| -      }
 | 
| +    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
| +    }
 | 
|  
 | 
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| +    exc->IP += 2;
 | 
|  
 | 
| -      switch ( CUR.opcode )
 | 
| -      {
 | 
| -      case 0x89:    /* IDEF */
 | 
| -      case 0x2C:    /* FDEF */
 | 
| -        CUR.error = FT_THROW( Nested_DEFS );
 | 
| -        return;
 | 
| +    for ( K = 0; K < L; K++ )
 | 
| +      args[K] = GetShortIns( exc );
 | 
|  
 | 
| -      case 0x2D:   /* ENDF */
 | 
| -        rec->end = CUR.IP;
 | 
| -        return;
 | 
| -      }
 | 
| +    exc->step_ins = FALSE;
 | 
| +    exc->new_top += L;
 | 
| +  }
 | 
| +
 | 
| +
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* PUSHB[abc]:   PUSH Bytes                                              */
 | 
| +  /* Opcode range: 0xB0-0xB7                                               */
 | 
| +  /* Stack:        --> uint32...                                           */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_PUSHB( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    FT_UShort  L, K;
 | 
| +
 | 
| +
 | 
| +    L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
 | 
| +
 | 
| +    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
|      }
 | 
| +
 | 
| +    for ( K = 1; K <= L; K++ )
 | 
| +      args[K - 1] = exc->code[exc->IP + K];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* ENDF[]:       END Function definition                                 */
 | 
| -  /* Opcode range: 0x2D                                                    */
 | 
| -  /* Stack:        -->                                                     */
 | 
| +  /* PUSHW[abc]:   PUSH Words                                              */
 | 
| +  /* Opcode range: 0xB8-0xBF                                               */
 | 
| +  /* Stack:        --> int32...                                            */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_ENDF( INS_ARG )
 | 
| +  Ins_PUSHW( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    TT_CallRec*  pRec;
 | 
| +    FT_UShort  L, K;
 | 
| +
 | 
| +
 | 
| +    L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
 | 
| +
 | 
| +    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
 | 
| +    {
 | 
| +      exc->error = FT_THROW( Stack_Overflow );
 | 
| +      return;
 | 
| +    }
 | 
| +
 | 
| +    exc->IP++;
 | 
| +
 | 
| +    for ( K = 0; K < L; K++ )
 | 
| +      args[K] = GetShortIns( exc );
 | 
| +
 | 
| +    exc->step_ins = FALSE;
 | 
| +  }
 | 
| +
 | 
| +
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* MANAGING THE GRAPHICS STATE                                           */
 | 
| +  /*                                                                       */
 | 
| +  /*************************************************************************/
 | 
| +
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
| +  static FT_Bool
 | 
| +  Ins_SxVTL( TT_ExecContext  exc,
 | 
| +             FT_UShort       aIdx1,
 | 
| +             FT_UShort       aIdx2,
 | 
| +             FT_UnitVector*  Vec )
 | 
| +  {
 | 
| +    FT_Long     A, B, C;
 | 
| +    FT_Vector*  p1;
 | 
| +    FT_Vector*  p2;
 | 
|  
 | 
| +    FT_Byte  opcode = exc->opcode;
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    CUR.sph_in_func_flags = 0x0000;
 | 
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    if ( CUR.callTop <= 0 )     /* We encountered an ENDF without a call */
 | 
| +    if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
 | 
| +         BOUNDS( aIdx2, exc->zp1.n_points ) )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( ENDF_In_Exec_Stream );
 | 
| -      return;
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
| +      return FAILURE;
 | 
|      }
 | 
|  
 | 
| -    CUR.callTop--;
 | 
| +    p1 = exc->zp1.cur + aIdx2;
 | 
| +    p2 = exc->zp2.cur + aIdx1;
 | 
|  
 | 
| -    pRec = &CUR.callStack[CUR.callTop];
 | 
| +    A = p1->x - p2->x;
 | 
| +    B = p1->y - p2->y;
 | 
|  
 | 
| -    pRec->Cur_Count--;
 | 
| +    /* If p1 == p2, SPvTL and SFvTL behave the same as */
 | 
| +    /* SPvTCA[X] and SFvTCA[X], respectively.          */
 | 
| +    /*                                                 */
 | 
| +    /* Confirmed by Greg Hitchcock.                    */
 | 
|  
 | 
| -    CUR.step_ins = FALSE;
 | 
| +    if ( A == 0 && B == 0 )
 | 
| +    {
 | 
| +      A      = 0x4000;
 | 
| +      opcode = 0;
 | 
| +    }
 | 
|  
 | 
| -    if ( pRec->Cur_Count > 0 )
 | 
| +    if ( ( opcode & 1 ) != 0 )
 | 
|      {
 | 
| -      CUR.callTop++;
 | 
| -      CUR.IP = pRec->Def->start;
 | 
| +      C =  B;   /* counter clockwise rotation */
 | 
| +      B =  A;
 | 
| +      A = -C;
 | 
|      }
 | 
| -    else
 | 
| -      /* Loop through the current function */
 | 
| -      INS_Goto_CodeRange( pRec->Caller_Range,
 | 
| -                          pRec->Caller_IP );
 | 
|  
 | 
| -    /* Exit the current call frame.                      */
 | 
| +    Normalize( A, B, Vec );
 | 
|  
 | 
| -    /* NOTE: If the last instruction of a program is a   */
 | 
| -    /*       CALL or LOOPCALL, the return address is     */
 | 
| -    /*       always out of the code range.  This is a    */
 | 
| -    /*       valid address, and it is why we do not test */
 | 
| -    /*       the result of Ins_Goto_CodeRange() here!    */
 | 
| +    return SUCCESS;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* CALL[]:       CALL function                                           */
 | 
| -  /* Opcode range: 0x2B                                                    */
 | 
| -  /* Stack:        uint32? -->                                             */
 | 
| +  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
 | 
| +  /* Opcode range: 0x00-0x01                                               */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  /* SPvTCA[a]:    Set PVector to Coordinate Axis                          */
 | 
| +  /* Opcode range: 0x02-0x03                                               */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  /* SFvTCA[a]:    Set FVector to Coordinate Axis                          */
 | 
| +  /* Opcode range: 0x04-0x05                                               */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_CALL( INS_ARG )
 | 
| +  Ins_SxyTCA( TT_ExecContext  exc )
 | 
|    {
 | 
| -    FT_ULong       F;
 | 
| -    TT_CallRec*    pCrec;
 | 
| -    TT_DefRecord*  def;
 | 
| -
 | 
| +    FT_Short  AA, BB;
 | 
|  
 | 
| -    /* first of all, check the index */
 | 
| +    FT_Byte  opcode = exc->opcode;
 | 
|  
 | 
| -    F = args[0];
 | 
| -    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
 | 
| -      goto Fail;
 | 
|  
 | 
| -    /* Except for some old Apple fonts, all functions in a TrueType */
 | 
| -    /* font are defined in increasing order, starting from 0.  This */
 | 
| -    /* means that we normally have                                  */
 | 
| -    /*                                                              */
 | 
| -    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
 | 
| -    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
 | 
| -    /*                                                              */
 | 
| -    /* If this isn't true, we need to look up the function table.   */
 | 
| +    AA = (FT_Short)( ( opcode & 1 ) << 14 );
 | 
| +    BB = (FT_Short)( AA ^ 0x4000 );
 | 
|  
 | 
| -    def = CUR.FDefs + F;
 | 
| -    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
 | 
| +    if ( opcode < 4 )
 | 
|      {
 | 
| -      /* look up the FDefs table */
 | 
| -      TT_DefRecord*  limit;
 | 
| +      exc->GS.projVector.x = AA;
 | 
| +      exc->GS.projVector.y = BB;
 | 
|  
 | 
| -
 | 
| -      def   = CUR.FDefs;
 | 
| -      limit = def + CUR.numFDefs;
 | 
| -
 | 
| -      while ( def < limit && def->opc != F )
 | 
| -        def++;
 | 
| -
 | 
| -      if ( def == limit )
 | 
| -        goto Fail;
 | 
| +      exc->GS.dualVector.x = AA;
 | 
| +      exc->GS.dualVector.y = BB;
 | 
|      }
 | 
| -
 | 
| -    /* check that the function is active */
 | 
| -    if ( !def->active )
 | 
| -      goto Fail;
 | 
| -
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                              &&
 | 
| -         CUR.ignore_x_mode                                             &&
 | 
| -         ( ( CUR.iup_called                                        &&
 | 
| -             ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
 | 
| -           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )       ) )
 | 
| -      goto Fail;
 | 
|      else
 | 
| -      CUR.sph_in_func_flags = def->sph_fdef_flags;
 | 
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| +      GUESS_VECTOR( projVector );
 | 
|  
 | 
| -    /* check the call stack */
 | 
| -    if ( CUR.callTop >= CUR.callSize )
 | 
| +    if ( ( opcode & 2 ) == 0 )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| +      exc->GS.freeVector.x = AA;
 | 
| +      exc->GS.freeVector.y = BB;
 | 
|      }
 | 
| +    else
 | 
| +      GUESS_VECTOR( freeVector );
 | 
|  
 | 
| -    pCrec = CUR.callStack + CUR.callTop;
 | 
| +    Compute_Funcs( exc );
 | 
| +  }
 | 
|  
 | 
| -    pCrec->Caller_Range = CUR.curRange;
 | 
| -    pCrec->Caller_IP    = CUR.IP + 1;
 | 
| -    pCrec->Cur_Count    = 1;
 | 
| -    pCrec->Def          = def;
 | 
|  
 | 
| -    CUR.callTop++;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SPvTL[a]:     Set PVector To Line                                     */
 | 
| +  /* Opcode range: 0x06-0x07                                               */
 | 
| +  /* Stack:        uint32 uint32 -->                                       */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SPVTL( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    if ( Ins_SxVTL( exc,
 | 
| +                    (FT_UShort)args[1],
 | 
| +                    (FT_UShort)args[0],
 | 
| +                    &exc->GS.projVector ) == SUCCESS )
 | 
| +    {
 | 
| +      exc->GS.dualVector = exc->GS.projVector;
 | 
| +      GUESS_VECTOR( freeVector );
 | 
| +      Compute_Funcs( exc );
 | 
| +    }
 | 
| +  }
 | 
|  
 | 
| -    INS_Goto_CodeRange( def->range,
 | 
| -                        def->start );
 | 
|  
 | 
| -    CUR.step_ins = FALSE;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SFvTL[a]:     Set FVector To Line                                     */
 | 
| +  /* Opcode range: 0x08-0x09                                               */
 | 
| +  /* Stack:        uint32 uint32 -->                                       */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SFVTL( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    if ( Ins_SxVTL( exc,
 | 
| +                    (FT_UShort)args[1],
 | 
| +                    (FT_UShort)args[0],
 | 
| +                    &exc->GS.freeVector ) == SUCCESS )
 | 
| +    {
 | 
| +      GUESS_VECTOR( projVector );
 | 
| +      Compute_Funcs( exc );
 | 
| +    }
 | 
| +  }
 | 
|  
 | 
| -    return;
 | 
|  
 | 
| -  Fail:
 | 
| -    CUR.error = FT_THROW( Invalid_Reference );
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SFvTPv[]:     Set FVector To PVector                                  */
 | 
| +  /* Opcode range: 0x0E                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SFVTPV( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    GUESS_VECTOR( projVector );
 | 
| +    exc->GS.freeVector = exc->GS.projVector;
 | 
| +    Compute_Funcs( exc );
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* LOOPCALL[]:   LOOP and CALL function                                  */
 | 
| -  /* Opcode range: 0x2A                                                    */
 | 
| -  /* Stack:        uint32? Eint16? -->                                     */
 | 
| +  /* SPvFS[]:      Set PVector From Stack                                  */
 | 
| +  /* Opcode range: 0x0A                                                    */
 | 
| +  /* Stack:        f2.14 f2.14 -->                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_LOOPCALL( INS_ARG )
 | 
| +  Ins_SPVFS( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    FT_ULong       F;
 | 
| -    TT_CallRec*    pCrec;
 | 
| -    TT_DefRecord*  def;
 | 
| +    FT_Short  S;
 | 
| +    FT_Long   X, Y;
 | 
|  
 | 
|  
 | 
| -    /* first of all, check the index */
 | 
| -    F = args[1];
 | 
| -    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
 | 
| -      goto Fail;
 | 
| +    /* Only use low 16bits, then sign extend */
 | 
| +    S = (FT_Short)args[1];
 | 
| +    Y = (FT_Long)S;
 | 
| +    S = (FT_Short)args[0];
 | 
| +    X = (FT_Long)S;
 | 
|  
 | 
| -    /* Except for some old Apple fonts, all functions in a TrueType */
 | 
| -    /* font are defined in increasing order, starting from 0.  This */
 | 
| -    /* means that we normally have                                  */
 | 
| -    /*                                                              */
 | 
| -    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
 | 
| -    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
 | 
| -    /*                                                              */
 | 
| -    /* If this isn't true, we need to look up the function table.   */
 | 
| +    Normalize( X, Y, &exc->GS.projVector );
 | 
|  
 | 
| -    def = CUR.FDefs + F;
 | 
| -    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
 | 
| -    {
 | 
| -      /* look up the FDefs table */
 | 
| -      TT_DefRecord*  limit;
 | 
| +    exc->GS.dualVector = exc->GS.projVector;
 | 
| +    GUESS_VECTOR( freeVector );
 | 
| +    Compute_Funcs( exc );
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -      def   = CUR.FDefs;
 | 
| -      limit = def + CUR.numFDefs;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SFvFS[]:      Set FVector From Stack                                  */
 | 
| +  /* Opcode range: 0x0B                                                    */
 | 
| +  /* Stack:        f2.14 f2.14 -->                                         */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SFVFS( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
| +  {
 | 
| +    FT_Short  S;
 | 
| +    FT_Long   X, Y;
 | 
|  
 | 
| -      while ( def < limit && def->opc != F )
 | 
| -        def++;
 | 
|  
 | 
| -      if ( def == limit )
 | 
| -        goto Fail;
 | 
| -    }
 | 
| +    /* Only use low 16bits, then sign extend */
 | 
| +    S = (FT_Short)args[1];
 | 
| +    Y = (FT_Long)S;
 | 
| +    S = (FT_Short)args[0];
 | 
| +    X = S;
 | 
|  
 | 
| -    /* check that the function is active */
 | 
| -    if ( !def->active )
 | 
| -      goto Fail;
 | 
| +    Normalize( X, Y, &exc->GS.freeVector );
 | 
| +    GUESS_VECTOR( projVector );
 | 
| +    Compute_Funcs( exc );
 | 
| +  }
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                    &&
 | 
| -         CUR.ignore_x_mode                                   &&
 | 
| -         ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
 | 
| -      goto Fail;
 | 
| -    else
 | 
| -      CUR.sph_in_func_flags = def->sph_fdef_flags;
 | 
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    /* check stack */
 | 
| -    if ( CUR.callTop >= CUR.callSize )
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* GPv[]:        Get Projection Vector                                   */
 | 
| +  /* Opcode range: 0x0C                                                    */
 | 
| +  /* Stack:        ef2.14 --> ef2.14                                       */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_GPV( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| +      args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
 | 
| +      args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
 | 
|      }
 | 
| -
 | 
| -    if ( args[0] > 0 )
 | 
| +    else
 | 
|      {
 | 
| -      pCrec = CUR.callStack + CUR.callTop;
 | 
| -
 | 
| -      pCrec->Caller_Range = CUR.curRange;
 | 
| -      pCrec->Caller_IP    = CUR.IP + 1;
 | 
| -      pCrec->Cur_Count    = (FT_Int)args[0];
 | 
| -      pCrec->Def          = def;
 | 
| -
 | 
| -      CUR.callTop++;
 | 
| -
 | 
| -      INS_Goto_CodeRange( def->range, def->start );
 | 
| -
 | 
| -      CUR.step_ins = FALSE;
 | 
| +      args[0] = exc->GS.projVector.x;
 | 
| +      args[1] = exc->GS.projVector.y;
 | 
|      }
 | 
| -
 | 
| -    return;
 | 
| -
 | 
| -  Fail:
 | 
| -    CUR.error = FT_THROW( Invalid_Reference );
 | 
| +#else
 | 
| +    args[0] = exc->GS.projVector.x;
 | 
| +    args[1] = exc->GS.projVector.y;
 | 
| +#endif
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* IDEF[]:       Instruction DEFinition                                  */
 | 
| -  /* Opcode range: 0x89                                                    */
 | 
| -  /* Stack:        Eint8 -->                                               */
 | 
| +  /* GFv[]:        Get Freedom Vector                                      */
 | 
| +  /* Opcode range: 0x0D                                                    */
 | 
| +  /* Stack:        ef2.14 --> ef2.14                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_IDEF( INS_ARG )
 | 
| +  Ins_GFV( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
| -    TT_DefRecord*  def;
 | 
| -    TT_DefRecord*  limit;
 | 
| -
 | 
| -
 | 
| -    /*  First of all, look for the same function in our table */
 | 
| -
 | 
| -    def   = CUR.IDefs;
 | 
| -    limit = def + CUR.numIDefs;
 | 
| -
 | 
| -    for ( ; def < limit; def++ )
 | 
| -      if ( def->opc == (FT_ULong)args[0] )
 | 
| -        break;
 | 
| -
 | 
| -    if ( def == limit )
 | 
| +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      /* check that there is enough room for a new instruction */
 | 
| -      if ( CUR.numIDefs >= CUR.maxIDefs )
 | 
| -      {
 | 
| -        CUR.error = FT_THROW( Too_Many_Instruction_Defs );
 | 
| -        return;
 | 
| -      }
 | 
| -      CUR.numIDefs++;
 | 
| +      args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
 | 
| +      args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
 | 
|      }
 | 
| -
 | 
| -    /* opcode must be unsigned 8-bit integer */
 | 
| -    if ( 0 > args[0] || args[0] > 0x00FF )
 | 
| +    else
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Too_Many_Instruction_Defs );
 | 
| -      return;
 | 
| +      args[0] = exc->GS.freeVector.x;
 | 
| +      args[1] = exc->GS.freeVector.y;
 | 
|      }
 | 
| +#else
 | 
| +    args[0] = exc->GS.freeVector.x;
 | 
| +    args[1] = exc->GS.freeVector.y;
 | 
| +#endif
 | 
| +  }
 | 
|  
 | 
| -    def->opc    = (FT_Byte)args[0];
 | 
| -    def->start  = CUR.IP + 1;
 | 
| -    def->range  = CUR.curRange;
 | 
| -    def->active = TRUE;
 | 
|  
 | 
| -    if ( (FT_ULong)args[0] > CUR.maxIns )
 | 
| -      CUR.maxIns = (FT_Byte)args[0];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SRP0[]:       Set Reference Point 0                                   */
 | 
| +  /* Opcode range: 0x10                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SRP0( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.rp0 = (FT_UShort)args[0];
 | 
| +  }
 | 
|  
 | 
| -    /* Now skip the whole function definition. */
 | 
| -    /* We don't allow nested IDEFs & FDEFs.    */
 | 
|  
 | 
| -    while ( SKIP_Code() == SUCCESS )
 | 
| -    {
 | 
| -      switch ( CUR.opcode )
 | 
| -      {
 | 
| -      case 0x89:   /* IDEF */
 | 
| -      case 0x2C:   /* FDEF */
 | 
| -        CUR.error = FT_THROW( Nested_DEFS );
 | 
| -        return;
 | 
| -      case 0x2D:   /* ENDF */
 | 
| -        return;
 | 
| -      }
 | 
| -    }
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SRP1[]:       Set Reference Point 1                                   */
 | 
| +  /* Opcode range: 0x11                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SRP1( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.rp1 = (FT_UShort)args[0];
 | 
| +  }
 | 
| +
 | 
| +
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SRP2[]:       Set Reference Point 2                                   */
 | 
| +  /* Opcode range: 0x12                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SRP2( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.rp2 = (FT_UShort)args[0];
 | 
| +  }
 | 
| +
 | 
| +
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SMD[]:        Set Minimum Distance                                    */
 | 
| +  /* Opcode range: 0x1A                                                    */
 | 
| +  /* Stack:        f26.6 -->                                               */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SMD( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.minimum_distance = args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* PUSHING DATA ONTO THE INTERPRETER STACK                               */
 | 
| -  /*                                                                       */
 | 
| -  /*   Instructions appear in the specification's order.                   */
 | 
| +  /* SCVTCI[]:     Set Control Value Table Cut In                          */
 | 
| +  /* Opcode range: 0x1D                                                    */
 | 
| +  /* Stack:        f26.6 -->                                               */
 | 
|    /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| +  static void
 | 
| +  Ins_SCVTCI( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
 | 
| +  }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* NPUSHB[]:     PUSH N Bytes                                            */
 | 
| -  /* Opcode range: 0x40                                                    */
 | 
| -  /* Stack:        --> uint32...                                           */
 | 
| +  /* SSWCI[]:      Set Single Width Cut In                                 */
 | 
| +  /* Opcode range: 0x1E                                                    */
 | 
| +  /* Stack:        f26.6 -->                                               */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_NPUSHB( INS_ARG )
 | 
| +  Ins_SSWCI( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
| -    FT_UShort  L, K;
 | 
| +    exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -    L = (FT_UShort)CUR.code[CUR.IP + 1];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SSW[]:        Set Single Width                                        */
 | 
| +  /* Opcode range: 0x1F                                                    */
 | 
| +  /* Stack:        int32? -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SSW( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.single_width_value = FT_MulFix( args[0],
 | 
| +                                            exc->tt_metrics.scale );
 | 
| +  }
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
 | 
| -    {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| -    }
 | 
|  
 | 
| -    for ( K = 1; K <= L; K++ )
 | 
| -      args[K - 1] = CUR.code[CUR.IP + K + 1];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* FLIPON[]:     Set auto-FLIP to ON                                     */
 | 
| +  /* Opcode range: 0x4D                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_FLIPON( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.auto_flip = TRUE;
 | 
| +  }
 | 
| +
 | 
|  
 | 
| -    CUR.new_top += L;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
 | 
| +  /* Opcode range: 0x4E                                                    */
 | 
| +  /* Stack: -->                                                            */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_FLIPOFF( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.auto_flip = FALSE;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* NPUSHW[]:     PUSH N Words                                            */
 | 
| -  /* Opcode range: 0x41                                                    */
 | 
| -  /* Stack:        --> int32...                                            */
 | 
| +  /* SANGW[]:      Set ANGle Weight                                        */
 | 
| +  /* Opcode range: 0x7E                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_NPUSHW( INS_ARG )
 | 
| +  Ins_SANGW( void )
 | 
|    {
 | 
| -    FT_UShort  L, K;
 | 
| +    /* instruction not supported anymore */
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -    L = (FT_UShort)CUR.code[CUR.IP + 1];
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SDB[]:        Set Delta Base                                          */
 | 
| +  /* Opcode range: 0x5E                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SDB( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +    exc->GS.delta_base = (FT_UShort)args[0];
 | 
| +  }
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
 | 
| -    {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| -    }
 | 
|  
 | 
| -    CUR.IP += 2;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SDS[]:        Set Delta Shift                                         */
 | 
| +  /* Opcode range: 0x5F                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SDS( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
| +  {
 | 
| +    if ( (FT_ULong)args[0] > 6UL )
 | 
| +      exc->error = FT_THROW( Bad_Argument );
 | 
| +    else
 | 
| +      exc->GS.delta_shift = (FT_UShort)args[0];
 | 
| +  }
 | 
|  
 | 
| -    for ( K = 0; K < L; K++ )
 | 
| -      args[K] = GET_ShortIns();
 | 
|  
 | 
| -    CUR.step_ins = FALSE;
 | 
| -    CUR.new_top += L;
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* RTHG[]:       Round To Half Grid                                      */
 | 
| +  /* Opcode range: 0x19                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_RTHG( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.round_state = TT_Round_To_Half_Grid;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_To_Half_Grid;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* PUSHB[abc]:   PUSH Bytes                                              */
 | 
| -  /* Opcode range: 0xB0-0xB7                                               */
 | 
| -  /* Stack:        --> uint32...                                           */
 | 
| +  /* RTG[]:        Round To Grid                                           */
 | 
| +  /* Opcode range: 0x18                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_PUSHB( INS_ARG )
 | 
| +  Ins_RTG( TT_ExecContext  exc )
 | 
|    {
 | 
| -    FT_UShort  L, K;
 | 
| +    exc->GS.round_state = TT_Round_To_Grid;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_To_Grid;
 | 
| +  }
 | 
|  
 | 
|  
 | 
| -    L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );
 | 
| +  /*************************************************************************/
 | 
| +  /* RTDG[]:       Round To Double Grid                                    */
 | 
| +  /* Opcode range: 0x3D                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_RTDG( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.round_state = TT_Round_To_Double_Grid;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_To_Double_Grid;
 | 
| +  }
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
 | 
| -    {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| -    }
 | 
|  
 | 
| -    for ( K = 1; K <= L; K++ )
 | 
| -      args[K - 1] = CUR.code[CUR.IP + K];
 | 
| +  /*************************************************************************/
 | 
| +  /* RUTG[]:       Round Up To Grid                                        */
 | 
| +  /* Opcode range: 0x7C                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_RUTG( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.round_state = TT_Round_Up_To_Grid;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_Up_To_Grid;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* PUSHW[abc]:   PUSH Words                                              */
 | 
| -  /* Opcode range: 0xB8-0xBF                                               */
 | 
| -  /* Stack:        --> int32...                                            */
 | 
| +  /* RDTG[]:       Round Down To Grid                                      */
 | 
| +  /* Opcode range: 0x7D                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_PUSHW( INS_ARG )
 | 
| +  Ins_RDTG( TT_ExecContext  exc )
 | 
|    {
 | 
| -    FT_UShort  L, K;
 | 
| -
 | 
| +    exc->GS.round_state = TT_Round_Down_To_Grid;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_Down_To_Grid;
 | 
| +  }
 | 
|  
 | 
| -    L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
 | 
| -    {
 | 
| -      CUR.error = FT_THROW( Stack_Overflow );
 | 
| -      return;
 | 
| -    }
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* ROFF[]:       Round OFF                                               */
 | 
| +  /* Opcode range: 0x7A                                                    */
 | 
| +  /* Stack:        -->                                                     */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_ROFF( TT_ExecContext  exc )
 | 
| +  {
 | 
| +    exc->GS.round_state = TT_Round_Off;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_None;
 | 
| +  }
 | 
|  
 | 
| -    CUR.IP++;
 | 
|  
 | 
| -    for ( K = 0; K < L; K++ )
 | 
| -      args[K] = GET_ShortIns();
 | 
| +  /*************************************************************************/
 | 
| +  /*                                                                       */
 | 
| +  /* SROUND[]:     Super ROUND                                             */
 | 
| +  /* Opcode range: 0x76                                                    */
 | 
| +  /* Stack:        Eint8 -->                                               */
 | 
| +  /*                                                                       */
 | 
| +  static void
 | 
| +  Ins_SROUND( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
| +  {
 | 
| +    SetSuperRound( exc, 0x4000, args[0] );
 | 
|  
 | 
| -    CUR.step_ins = FALSE;
 | 
| +    exc->GS.round_state = TT_Round_Super;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_Super;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* MANAGING THE GRAPHICS STATE                                           */
 | 
| -  /*                                                                       */
 | 
| -  /*  Instructions appear in the specs' order.                             */
 | 
| +  /* S45ROUND[]:   Super ROUND 45 degrees                                  */
 | 
| +  /* Opcode range: 0x77                                                    */
 | 
| +  /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
| -  /*************************************************************************/
 | 
| +  static void
 | 
| +  Ins_S45ROUND( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
| +  {
 | 
| +    SetSuperRound( exc, 0x2D41, args[0] );
 | 
| +
 | 
| +    exc->GS.round_state = TT_Round_Super_45;
 | 
| +    exc->func_round     = (TT_Round_Func)Round_Super_45;
 | 
| +  }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
| @@ -5269,7 +4776,8 @@
 | 
|    /*      along the dual projection vector!                                */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_GC( INS_ARG )
 | 
| +  Ins_GC( TT_ExecContext  exc,
 | 
| +          FT_Long*        args )
 | 
|    {
 | 
|      FT_ULong    L;
 | 
|      FT_F26Dot6  R;
 | 
| @@ -5277,18 +4785,18 @@
 | 
|  
 | 
|      L = (FT_ULong)args[0];
 | 
|  
 | 
| -    if ( BOUNDSL( L, CUR.zp2.n_points ) )
 | 
| +    if ( BOUNDSL( L, exc->zp2.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        R = 0;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      if ( CUR.opcode & 1 )
 | 
| -        R = CUR_fast_dualproj( &CUR.zp2.org[L] );
 | 
| +      if ( exc->opcode & 1 )
 | 
| +        R = FAST_DUALPROJ( &exc->zp2.org[L] );
 | 
|        else
 | 
| -        R = CUR_fast_project( &CUR.zp2.cur[L] );
 | 
| +        R = FAST_PROJECT( &exc->zp2.cur[L] );
 | 
|      }
 | 
|  
 | 
|      args[0] = R;
 | 
| @@ -5306,7 +4814,8 @@
 | 
|    /*   OA := OA + ( value - OA.p )/( f.p ) * f                             */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SCFS( INS_ARG )
 | 
| +  Ins_SCFS( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      FT_Long    K;
 | 
|      FT_UShort  L;
 | 
| @@ -5314,21 +4823,21 @@
 | 
|  
 | 
|      L = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.zp2.n_points ) )
 | 
| +    if ( BOUNDS( L, exc->zp2.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    K = CUR_fast_project( &CUR.zp2.cur[L] );
 | 
| +    K = FAST_PROJECT( &exc->zp2.cur[L] );
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp2, L, args[1] - K );
 | 
| +    exc->func_move( exc, &exc->zp2, L, args[1] - K );
 | 
|  
 | 
|      /* UNDOCUMENTED!  The MS rasterizer does that with */
 | 
|      /* twilight points (confirmed by Greg Hitchcock)   */
 | 
| -    if ( CUR.GS.gep2 == 0 )
 | 
| -      CUR.zp2.org[L] = CUR.zp2.cur[L];
 | 
| +    if ( exc->GS.gep2 == 0 )
 | 
| +      exc->zp2.org[L] = exc->zp2.cur[L];
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5348,7 +4857,8 @@
 | 
|    /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1!                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MD( INS_ARG )
 | 
| +  Ins_MD( TT_ExecContext  exc,
 | 
| +          FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   K, L;
 | 
|      FT_F26Dot6  D;
 | 
| @@ -5357,50 +4867,50 @@
 | 
|      K = (FT_UShort)args[1];
 | 
|      L = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( L, CUR.zp0.n_points ) ||
 | 
| -         BOUNDS( K, CUR.zp1.n_points ) )
 | 
| +    if ( BOUNDS( L, exc->zp0.n_points ) ||
 | 
| +         BOUNDS( K, exc->zp1.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        D = 0;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      if ( CUR.opcode & 1 )
 | 
| -        D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
 | 
| +      if ( exc->opcode & 1 )
 | 
| +        D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
 | 
|        else
 | 
|        {
 | 
|          /* XXX: UNDOCUMENTED: twilight zone special case */
 | 
|  
 | 
| -        if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
 | 
| +        if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
 | 
|          {
 | 
| -          FT_Vector*  vec1 = CUR.zp0.org + L;
 | 
| -          FT_Vector*  vec2 = CUR.zp1.org + K;
 | 
| +          FT_Vector*  vec1 = exc->zp0.org + L;
 | 
| +          FT_Vector*  vec2 = exc->zp1.org + K;
 | 
|  
 | 
|  
 | 
| -          D = CUR_Func_dualproj( vec1, vec2 );
 | 
| +          D = DUALPROJ( vec1, vec2 );
 | 
|          }
 | 
|          else
 | 
|          {
 | 
| -          FT_Vector*  vec1 = CUR.zp0.orus + L;
 | 
| -          FT_Vector*  vec2 = CUR.zp1.orus + K;
 | 
| +          FT_Vector*  vec1 = exc->zp0.orus + L;
 | 
| +          FT_Vector*  vec2 = exc->zp1.orus + K;
 | 
|  
 | 
|  
 | 
| -          if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
 | 
| +          if ( exc->metrics.x_scale == exc->metrics.y_scale )
 | 
|            {
 | 
|              /* this should be faster */
 | 
| -            D = CUR_Func_dualproj( vec1, vec2 );
 | 
| -            D = FT_MulFix( D, CUR.metrics.x_scale );
 | 
| +            D = DUALPROJ( vec1, vec2 );
 | 
| +            D = FT_MulFix( D, exc->metrics.x_scale );
 | 
|            }
 | 
|            else
 | 
|            {
 | 
|              FT_Vector  vec;
 | 
|  
 | 
|  
 | 
| -            vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
 | 
| -            vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
 | 
| +            vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
 | 
| +            vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 | 
|  
 | 
| -            D = CUR_fast_dualproj( &vec );
 | 
| +            D = FAST_DUALPROJ( &vec );
 | 
|            }
 | 
|          }
 | 
|        }
 | 
| @@ -5408,8 +4918,9 @@
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|      /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
 | 
| -    if ( SUBPIXEL_HINTING                       &&
 | 
| -         CUR.ignore_x_mode && FT_ABS( D ) == 64 )
 | 
| +    if ( SUBPIXEL_HINTING   &&
 | 
| +         exc->ignore_x_mode &&
 | 
| +         FT_ABS( D ) == 64  )
 | 
|        D += 1;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| @@ -5419,61 +4930,63 @@
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
| -  /* SDPVTL[a]:    Set Dual PVector to Line                                */
 | 
| +  /* SDPvTL[a]:    Set Dual PVector to Line                                */
 | 
|    /* Opcode range: 0x86-0x87                                               */
 | 
|    /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SDPVTL( INS_ARG )
 | 
| +  Ins_SDPVTL( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
|      FT_Long    A, B, C;
 | 
|      FT_UShort  p1, p2;            /* was FT_Int in pas type ERROR */
 | 
| -    FT_Int     aOpc = CUR.opcode;
 | 
| +
 | 
| +    FT_Byte  opcode = exc->opcode;
 | 
|  
 | 
|  
 | 
|      p1 = (FT_UShort)args[1];
 | 
|      p2 = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( p2, CUR.zp1.n_points ) ||
 | 
| -         BOUNDS( p1, CUR.zp2.n_points ) )
 | 
| +    if ( BOUNDS( p2, exc->zp1.n_points ) ||
 | 
| +         BOUNDS( p1, exc->zp2.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      {
 | 
| -      FT_Vector* v1 = CUR.zp1.org + p2;
 | 
| -      FT_Vector* v2 = CUR.zp2.org + p1;
 | 
| +      FT_Vector* v1 = exc->zp1.org + p2;
 | 
| +      FT_Vector* v2 = exc->zp2.org + p1;
 | 
|  
 | 
|  
 | 
|        A = v1->x - v2->x;
 | 
|        B = v1->y - v2->y;
 | 
|  
 | 
| -      /* If v1 == v2, SDPVTL behaves the same as */
 | 
| +      /* If v1 == v2, SDPvTL behaves the same as */
 | 
|        /* SVTCA[X], respectively.                 */
 | 
|        /*                                         */
 | 
|        /* Confirmed by Greg Hitchcock.            */
 | 
|  
 | 
|        if ( A == 0 && B == 0 )
 | 
|        {
 | 
| -        A    = 0x4000;
 | 
| -        aOpc = 0;
 | 
| +        A      = 0x4000;
 | 
| +        opcode = 0;
 | 
|        }
 | 
|      }
 | 
|  
 | 
| -    if ( ( aOpc & 1 ) != 0 )
 | 
| +    if ( ( opcode & 1 ) != 0 )
 | 
|      {
 | 
|        C =  B;   /* counter clockwise rotation */
 | 
|        B =  A;
 | 
|        A = -C;
 | 
|      }
 | 
|  
 | 
| -    NORMalize( A, B, &CUR.GS.dualVector );
 | 
| +    Normalize( A, B, &exc->GS.dualVector );
 | 
|  
 | 
|      {
 | 
| -      FT_Vector*  v1 = CUR.zp1.cur + p2;
 | 
| -      FT_Vector*  v2 = CUR.zp2.cur + p1;
 | 
| +      FT_Vector*  v1 = exc->zp1.cur + p2;
 | 
| +      FT_Vector*  v2 = exc->zp2.cur + p1;
 | 
|  
 | 
|  
 | 
|        A = v1->x - v2->x;
 | 
| @@ -5481,23 +4994,21 @@
 | 
|  
 | 
|        if ( A == 0 && B == 0 )
 | 
|        {
 | 
| -        A    = 0x4000;
 | 
| -        aOpc = 0;
 | 
| +        A      = 0x4000;
 | 
| +        opcode = 0;
 | 
|        }
 | 
|      }
 | 
|  
 | 
| -    if ( ( aOpc & 1 ) != 0 )
 | 
| +    if ( ( opcode & 1 ) != 0 )
 | 
|      {
 | 
|        C =  B;   /* counter clockwise rotation */
 | 
|        B =  A;
 | 
|        A = -C;
 | 
|      }
 | 
|  
 | 
| -    NORMalize( A, B, &CUR.GS.projVector );
 | 
| -
 | 
| +    Normalize( A, B, &exc->GS.projVector );
 | 
|      GUESS_VECTOR( freeVector );
 | 
| -
 | 
| -    COMPUTE_Funcs();
 | 
| +    Compute_Funcs( exc );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5508,25 +5019,26 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SZP0( INS_ARG )
 | 
| +  Ins_SZP0( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      switch ( (FT_Int)args[0] )
 | 
|      {
 | 
|      case 0:
 | 
| -      CUR.zp0 = CUR.twilight;
 | 
| +      exc->zp0 = exc->twilight;
 | 
|        break;
 | 
|  
 | 
|      case 1:
 | 
| -      CUR.zp0 = CUR.pts;
 | 
| +      exc->zp0 = exc->pts;
 | 
|        break;
 | 
|  
 | 
|      default:
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    CUR.GS.gep0 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep0 = (FT_UShort)args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5537,25 +5049,26 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SZP1( INS_ARG )
 | 
| +  Ins_SZP1( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      switch ( (FT_Int)args[0] )
 | 
|      {
 | 
|      case 0:
 | 
| -      CUR.zp1 = CUR.twilight;
 | 
| +      exc->zp1 = exc->twilight;
 | 
|        break;
 | 
|  
 | 
|      case 1:
 | 
| -      CUR.zp1 = CUR.pts;
 | 
| +      exc->zp1 = exc->pts;
 | 
|        break;
 | 
|  
 | 
|      default:
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    CUR.GS.gep1 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep1 = (FT_UShort)args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5566,25 +5079,26 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SZP2( INS_ARG )
 | 
| +  Ins_SZP2( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      switch ( (FT_Int)args[0] )
 | 
|      {
 | 
|      case 0:
 | 
| -      CUR.zp2 = CUR.twilight;
 | 
| +      exc->zp2 = exc->twilight;
 | 
|        break;
 | 
|  
 | 
|      case 1:
 | 
| -      CUR.zp2 = CUR.pts;
 | 
| +      exc->zp2 = exc->pts;
 | 
|        break;
 | 
|  
 | 
|      default:
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    CUR.GS.gep2 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep2 = (FT_UShort)args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5595,60 +5109,82 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SZPS( INS_ARG )
 | 
| +  Ins_SZPS( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      switch ( (FT_Int)args[0] )
 | 
|      {
 | 
|      case 0:
 | 
| -      CUR.zp0 = CUR.twilight;
 | 
| +      exc->zp0 = exc->twilight;
 | 
|        break;
 | 
|  
 | 
|      case 1:
 | 
| -      CUR.zp0 = CUR.pts;
 | 
| +      exc->zp0 = exc->pts;
 | 
|        break;
 | 
|  
 | 
|      default:
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    CUR.zp1 = CUR.zp0;
 | 
| -    CUR.zp2 = CUR.zp0;
 | 
| +    exc->zp1 = exc->zp0;
 | 
| +    exc->zp2 = exc->zp0;
 | 
|  
 | 
| -    CUR.GS.gep0 = (FT_UShort)args[0];
 | 
| -    CUR.GS.gep1 = (FT_UShort)args[0];
 | 
| -    CUR.GS.gep2 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep0 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep1 = (FT_UShort)args[0];
 | 
| +    exc->GS.gep2 = (FT_UShort)args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
|    /* INSTCTRL[]:   INSTruction ConTRoL                                     */
 | 
| -  /* Opcode range: 0x8e                                                    */
 | 
| +  /* Opcode range: 0x8E                                                    */
 | 
|    /* Stack:        int32 int32 -->                                         */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_INSTCTRL( INS_ARG )
 | 
| +  Ins_INSTCTRL( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
| -    FT_Long  K, L;
 | 
| +    FT_ULong  K, L, Kf;
 | 
|  
 | 
|  
 | 
| -    K = args[1];
 | 
| -    L = args[0];
 | 
| +    K = (FT_ULong)args[1];
 | 
| +    L = (FT_ULong)args[0];
 | 
|  
 | 
| -    if ( K < 1 || K > 2 )
 | 
| +    /* selector values cannot be `OR'ed;                 */
 | 
| +    /* they are indices starting with index 1, not flags */
 | 
| +    if ( K < 1 || K > 3 )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| +    /* convert index to flag value */
 | 
| +    Kf = 1 << ( K - 1 );
 | 
| +
 | 
|      if ( L != 0 )
 | 
| -        L = K;
 | 
| +    {
 | 
| +      /* arguments to selectors look like flag values */
 | 
| +      if ( L != Kf )
 | 
| +      {
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
| +        return;
 | 
| +      }
 | 
| +    }
 | 
|  
 | 
| -    CUR.GS.instruct_control = FT_BOOL(
 | 
| -      ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
 | 
| +    exc->GS.instruct_control &= ~(FT_Byte)Kf;
 | 
| +    exc->GS.instruct_control |= (FT_Byte)L;
 | 
| +
 | 
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| +    /* INSTCTRL modifying flag 3 also has an effect */
 | 
| +    /* outside of the CVT program                   */
 | 
| +    if ( K == 3 )
 | 
| +      exc->ignore_x_mode = FT_BOOL( L == 4 );
 | 
| +#endif
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5659,7 +5195,8 @@
 | 
|    /* Stack:        uint32? -->                                             */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SCANCTRL( INS_ARG )
 | 
| +  Ins_SCANCTRL( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
|      FT_Int  A;
 | 
|  
 | 
| @@ -5669,32 +5206,32 @@
 | 
|  
 | 
|      if ( A == 0xFF )
 | 
|      {
 | 
| -      CUR.GS.scan_control = TRUE;
 | 
| +      exc->GS.scan_control = TRUE;
 | 
|        return;
 | 
|      }
 | 
|      else if ( A == 0 )
 | 
|      {
 | 
| -      CUR.GS.scan_control = FALSE;
 | 
| +      exc->GS.scan_control = FALSE;
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
 | 
| -      CUR.GS.scan_control = TRUE;
 | 
| +    if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
 | 
| +      exc->GS.scan_control = TRUE;
 | 
|  
 | 
| -    if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
 | 
| -      CUR.GS.scan_control = TRUE;
 | 
| +    if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
 | 
| +      exc->GS.scan_control = TRUE;
 | 
|  
 | 
| -    if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
 | 
| -      CUR.GS.scan_control = TRUE;
 | 
| +    if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
 | 
| +      exc->GS.scan_control = TRUE;
 | 
|  
 | 
| -    if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
 | 
| -      CUR.GS.scan_control = FALSE;
 | 
| +    if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
 | 
| +      exc->GS.scan_control = FALSE;
 | 
|  
 | 
| -    if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
 | 
| -      CUR.GS.scan_control = FALSE;
 | 
| +    if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
 | 
| +      exc->GS.scan_control = FALSE;
 | 
|  
 | 
| -    if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
 | 
| -      CUR.GS.scan_control = FALSE;
 | 
| +    if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
 | 
| +      exc->GS.scan_control = FALSE;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5705,10 +5242,11 @@
 | 
|    /* Stack:        uint32? -->                                             */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SCANTYPE( INS_ARG )
 | 
| +  Ins_SCANTYPE( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
|      if ( args[0] >= 0 )
 | 
| -      CUR.GS.scan_type = (FT_Int)args[0];
 | 
| +      exc->GS.scan_type = (FT_Int)args[0];
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5716,8 +5254,6 @@
 | 
|    /*                                                                       */
 | 
|    /* MANAGING OUTLINES                                                     */
 | 
|    /*                                                                       */
 | 
| -  /*   Instructions appear in the specification's order.                   */
 | 
| -  /*                                                                       */
 | 
|    /*************************************************************************/
 | 
|  
 | 
|  
 | 
| @@ -5728,43 +5264,41 @@
 | 
|    /* Stack:        uint32... -->                                           */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FLIPPT( INS_ARG )
 | 
| +  Ins_FLIPPT( TT_ExecContext  exc )
 | 
|    {
 | 
|      FT_UShort  point;
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
|  
 | 
| -
 | 
| -    if ( CUR.top < CUR.GS.loop )
 | 
| +    if ( exc->top < exc->GS.loop )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Too_Few_Arguments );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
| -    while ( CUR.GS.loop > 0 )
 | 
| +    while ( exc->GS.loop > 0 )
 | 
|      {
 | 
| -      CUR.args--;
 | 
| +      exc->args--;
 | 
|  
 | 
| -      point = (FT_UShort)CUR.stack[CUR.args];
 | 
| +      point = (FT_UShort)exc->stack[exc->args];
 | 
|  
 | 
| -      if ( BOUNDS( point, CUR.pts.n_points ) )
 | 
| +      if ( BOUNDS( point, exc->pts.n_points ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|        }
 | 
|        else
 | 
| -        CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;
 | 
| +        exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
 | 
|  
 | 
| -      CUR.GS.loop--;
 | 
| +      exc->GS.loop--;
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.loop = 1;
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->GS.loop = 1;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5775,7 +5309,8 @@
 | 
|    /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FLIPRGON( INS_ARG )
 | 
| +  Ins_FLIPRGON( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort  I, K, L;
 | 
|  
 | 
| @@ -5783,16 +5318,16 @@
 | 
|      K = (FT_UShort)args[1];
 | 
|      L = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( K, CUR.pts.n_points ) ||
 | 
| -         BOUNDS( L, CUR.pts.n_points ) )
 | 
| +    if ( BOUNDS( K, exc->pts.n_points ) ||
 | 
| +         BOUNDS( L, exc->pts.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      for ( I = L; I <= K; I++ )
 | 
| -      CUR.pts.tags[I] |= FT_CURVE_TAG_ON;
 | 
| +      exc->pts.tags[I] |= FT_CURVE_TAG_ON;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5803,7 +5338,8 @@
 | 
|    /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_FLIPRGOFF( INS_ARG )
 | 
| +  Ins_FLIPRGOFF( TT_ExecContext  exc,
 | 
| +                 FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort  I, K, L;
 | 
|  
 | 
| @@ -5811,45 +5347,46 @@
 | 
|      K = (FT_UShort)args[1];
 | 
|      L = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( K, CUR.pts.n_points ) ||
 | 
| -         BOUNDS( L, CUR.pts.n_points ) )
 | 
| +    if ( BOUNDS( K, exc->pts.n_points ) ||
 | 
| +         BOUNDS( L, exc->pts.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      for ( I = L; I <= K; I++ )
 | 
| -      CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;
 | 
| +      exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
 | 
|    }
 | 
|  
 | 
|  
 | 
|    static FT_Bool
 | 
| -  Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6*   x,
 | 
| -                                       FT_F26Dot6*   y,
 | 
| -                                       TT_GlyphZone  zone,
 | 
| -                                       FT_UShort*    refp )
 | 
| +  Compute_Point_Displacement( TT_ExecContext  exc,
 | 
| +                              FT_F26Dot6*     x,
 | 
| +                              FT_F26Dot6*     y,
 | 
| +                              TT_GlyphZone    zone,
 | 
| +                              FT_UShort*      refp )
 | 
|    {
 | 
|      TT_GlyphZoneRec  zp;
 | 
|      FT_UShort        p;
 | 
|      FT_F26Dot6       d;
 | 
|  
 | 
|  
 | 
| -    if ( CUR.opcode & 1 )
 | 
| +    if ( exc->opcode & 1 )
 | 
|      {
 | 
| -      zp = CUR.zp0;
 | 
| -      p  = CUR.GS.rp1;
 | 
| +      zp = exc->zp0;
 | 
| +      p  = exc->GS.rp1;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      zp = CUR.zp1;
 | 
| -      p  = CUR.GS.rp2;
 | 
| +      zp = exc->zp1;
 | 
| +      p  = exc->GS.rp2;
 | 
|      }
 | 
|  
 | 
|      if ( BOUNDS( p, zp.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        *refp = 0;
 | 
|        return FAILURE;
 | 
|      }
 | 
| @@ -5857,12 +5394,12 @@
 | 
|      *zone = zp;
 | 
|      *refp = p;
 | 
|  
 | 
| -    d = CUR_Func_project( zp.cur + p, zp.org + p );
 | 
| +    d = PROJECT( zp.cur + p, zp.org + p );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      if ( CUR.GS.both_x_axis )
 | 
| +      if ( exc->GS.both_x_axis )
 | 
|        {
 | 
|          *x = d;
 | 
|          *y = 0;
 | 
| @@ -5876,8 +5413,8 @@
 | 
|      else
 | 
|  #endif
 | 
|      {
 | 
| -      *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
 | 
| -      *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
 | 
| +      *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
 | 
| +      *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
 | 
|      }
 | 
|  
 | 
|      return SUCCESS;
 | 
| @@ -5885,42 +5422,43 @@
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Move_Zp2_Point( EXEC_OP_ FT_UShort   point,
 | 
| -                           FT_F26Dot6  dx,
 | 
| -                           FT_F26Dot6  dy,
 | 
| -                           FT_Bool     touch )
 | 
| +  Move_Zp2_Point( TT_ExecContext  exc,
 | 
| +                  FT_UShort       point,
 | 
| +                  FT_F26Dot6      dx,
 | 
| +                  FT_F26Dot6      dy,
 | 
| +                  FT_Bool         touch )
 | 
|    {
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      if ( CUR.GS.both_x_axis )
 | 
| +      if ( exc->GS.both_x_axis )
 | 
|        {
 | 
| -        CUR.zp2.cur[point].x += dx;
 | 
| +        exc->zp2.cur[point].x += dx;
 | 
|          if ( touch )
 | 
| -          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
 | 
| +          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
 | 
|        }
 | 
|        else
 | 
|        {
 | 
| -        CUR.zp2.cur[point].y += dy;
 | 
| +        exc->zp2.cur[point].y += dy;
 | 
|          if ( touch )
 | 
| -          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
 | 
| +          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
 | 
|        }
 | 
|        return;
 | 
|      }
 | 
|  #endif
 | 
|  
 | 
| -    if ( CUR.GS.freeVector.x != 0 )
 | 
| +    if ( exc->GS.freeVector.x != 0 )
 | 
|      {
 | 
| -      CUR.zp2.cur[point].x += dx;
 | 
| +      exc->zp2.cur[point].x += dx;
 | 
|        if ( touch )
 | 
| -        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
 | 
| +        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
 | 
|      }
 | 
|  
 | 
| -    if ( CUR.GS.freeVector.y != 0 )
 | 
| +    if ( exc->GS.freeVector.y != 0 )
 | 
|      {
 | 
| -      CUR.zp2.cur[point].y += dy;
 | 
| +      exc->zp2.cur[point].y += dy;
 | 
|        if ( touch )
 | 
| -        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
 | 
| +        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -5932,57 +5470,54 @@
 | 
|    /* Stack:        uint32... -->                                           */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SHP( INS_ARG )
 | 
| +  Ins_SHP( TT_ExecContext  exc )
 | 
|    {
 | 
|      TT_GlyphZoneRec  zp;
 | 
|      FT_UShort        refp;
 | 
|  
 | 
| -    FT_F26Dot6       dx,
 | 
| -                     dy;
 | 
| +    FT_F26Dot6       dx, dy;
 | 
|      FT_UShort        point;
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
|  
 | 
| -
 | 
| -    if ( CUR.top < CUR.GS.loop )
 | 
| +    if ( exc->top < exc->GS.loop )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
| -    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
 | 
| +    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
 | 
|        return;
 | 
|  
 | 
| -    while ( CUR.GS.loop > 0 )
 | 
| +    while ( exc->GS.loop > 0 )
 | 
|      {
 | 
| -      CUR.args--;
 | 
| -      point = (FT_UShort)CUR.stack[CUR.args];
 | 
| +      exc->args--;
 | 
| +      point = (FT_UShort)exc->stack[exc->args];
 | 
|  
 | 
| -      if ( BOUNDS( point, CUR.zp2.n_points ) )
 | 
| +      if ( BOUNDS( point, exc->zp2.n_points ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|        }
 | 
|        else
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|        /* doesn't follow Cleartype spec but produces better result */
 | 
| -      if ( SUBPIXEL_HINTING  &&
 | 
| -           CUR.ignore_x_mode )
 | 
| -        MOVE_Zp2_Point( point, 0, dy, TRUE );
 | 
| +      if ( SUBPIXEL_HINTING   &&
 | 
| +           exc->ignore_x_mode )
 | 
| +        Move_Zp2_Point( exc, point, 0, dy, TRUE );
 | 
|        else
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| -        MOVE_Zp2_Point( point, dx, dy, TRUE );
 | 
| +        Move_Zp2_Point( exc, point, dx, dy, TRUE );
 | 
|  
 | 
| -      CUR.GS.loop--;
 | 
| +      exc->GS.loop--;
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.loop = 1;
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->GS.loop = 1;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -5997,7 +5532,8 @@
 | 
|    /*               zero which includes all points of it.                   */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SHC( INS_ARG )
 | 
| +  Ins_SHC( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
|      TT_GlyphZoneRec  zp;
 | 
|      FT_UShort        refp;
 | 
| @@ -6007,36 +5543,36 @@
 | 
|      FT_UShort        start, limit, i;
 | 
|  
 | 
|  
 | 
| -    contour = (FT_UShort)args[0];
 | 
| -    bounds  = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
 | 
| +    contour = (FT_Short)args[0];
 | 
| +    bounds  = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
 | 
|  
 | 
|      if ( BOUNDS( contour, bounds ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
 | 
| +    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
 | 
|        return;
 | 
|  
 | 
|      if ( contour == 0 )
 | 
|        start = 0;
 | 
|      else
 | 
| -      start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
 | 
| -                           CUR.zp2.first_point );
 | 
| +      start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
 | 
| +                           exc->zp2.first_point );
 | 
|  
 | 
|      /* we use the number of points if in the twilight zone */
 | 
| -    if ( CUR.GS.gep2 == 0 )
 | 
| -      limit = CUR.zp2.n_points;
 | 
| +    if ( exc->GS.gep2 == 0 )
 | 
| +      limit = exc->zp2.n_points;
 | 
|      else
 | 
| -      limit = (FT_UShort)( CUR.zp2.contours[contour] -
 | 
| -                           CUR.zp2.first_point + 1 );
 | 
| +      limit = (FT_UShort)( exc->zp2.contours[contour] -
 | 
| +                           exc->zp2.first_point + 1 );
 | 
|  
 | 
|      for ( i = start; i < limit; i++ )
 | 
|      {
 | 
| -      if ( zp.cur != CUR.zp2.cur || refp != i )
 | 
| -        MOVE_Zp2_Point( i, dx, dy, TRUE );
 | 
| +      if ( zp.cur != exc->zp2.cur || refp != i )
 | 
| +        Move_Zp2_Point( exc, i, dx, dy, TRUE );
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -6048,7 +5584,8 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SHZ( INS_ARG )
 | 
| +  Ins_SHZ( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
|      TT_GlyphZoneRec  zp;
 | 
|      FT_UShort        refp;
 | 
| @@ -6060,30 +5597,30 @@
 | 
|  
 | 
|      if ( BOUNDS( args[0], 2 ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
 | 
| +    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
 | 
|        return;
 | 
|  
 | 
|      /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points.     */
 | 
|      /*      Twilight zone has no real contours, so use `n_points'. */
 | 
|      /*      Normal zone's `n_points' includes phantoms, so must    */
 | 
|      /*      use end of last contour.                               */
 | 
| -    if ( CUR.GS.gep2 == 0 )
 | 
| -      limit = (FT_UShort)CUR.zp2.n_points;
 | 
| -    else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
 | 
| -      limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
 | 
| +    if ( exc->GS.gep2 == 0 )
 | 
| +      limit = (FT_UShort)exc->zp2.n_points;
 | 
| +    else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
 | 
| +      limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
 | 
|      else
 | 
|        limit = 0;
 | 
|  
 | 
|      /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
 | 
|      for ( i = 0; i < limit; i++ )
 | 
|      {
 | 
| -      if ( zp.cur != CUR.zp2.cur || refp != i )
 | 
| -        MOVE_Zp2_Point( i, dx, dy, FALSE );
 | 
| +      if ( zp.cur != exc->zp2.cur || refp != i )
 | 
| +        Move_Zp2_Point( exc, i, dx, dy, FALSE );
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -6095,7 +5632,8 @@
 | 
|    /* Stack:        f26.6 uint32... -->                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_SHPIX( INS_ARG )
 | 
| +  Ins_SHPIX( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
|      FT_F26Dot6  dx, dy;
 | 
|      FT_UShort   point;
 | 
| @@ -6104,17 +5642,17 @@
 | 
|  #endif
 | 
|  
 | 
|  
 | 
| -    if ( CUR.top < CUR.GS.loop + 1 )
 | 
| +    if ( exc->top < exc->GS.loop + 1 )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
| -      if ( CUR.GS.both_x_axis )
 | 
| +      if ( exc->GS.both_x_axis )
 | 
|        {
 | 
|          dx = (FT_UInt32)args[0];
 | 
|          dy = 0;
 | 
| @@ -6128,115 +5666,115 @@
 | 
|      else
 | 
|  #endif
 | 
|      {
 | 
| -      dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
 | 
| -      dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
 | 
| +      dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
 | 
| +      dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
 | 
|      }
 | 
|  
 | 
| -    while ( CUR.GS.loop > 0 )
 | 
| +    while ( exc->GS.loop > 0 )
 | 
|      {
 | 
| -      CUR.args--;
 | 
| +      exc->args--;
 | 
|  
 | 
| -      point = (FT_UShort)CUR.stack[CUR.args];
 | 
| +      point = (FT_UShort)exc->stack[exc->args];
 | 
|  
 | 
| -      if ( BOUNDS( point, CUR.zp2.n_points ) )
 | 
| +      if ( BOUNDS( point, exc->zp2.n_points ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|        }
 | 
|        else
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|        {
 | 
| -        /*  If not using ignore_x_mode rendering, allow ZP2 move.          */
 | 
| -        /*  If inline deltas aren't allowed, skip ZP2 move.                */
 | 
| -        /*  If using ignore_x_mode rendering, allow ZP2 point move if:     */
 | 
| -        /*   - freedom vector is y and sph_compatibility_mode is off       */
 | 
| -        /*   - the glyph is composite and the move is in the Y direction   */
 | 
| -        /*   - the glyph is specifically set to allow SHPIX moves          */
 | 
| -        /*   - the move is on a previously Y-touched point                 */
 | 
| -
 | 
| -        if ( SUBPIXEL_HINTING  &&
 | 
| -             CUR.ignore_x_mode )
 | 
| +        /*  If not using ignore_x_mode rendering, allow ZP2 move.        */
 | 
| +        /*  If inline deltas aren't allowed, skip ZP2 move.              */
 | 
| +        /*  If using ignore_x_mode rendering, allow ZP2 point move if:   */
 | 
| +        /*   - freedom vector is y and sph_compatibility_mode is off     */
 | 
| +        /*   - the glyph is composite and the move is in the Y direction */
 | 
| +        /*   - the glyph is specifically set to allow SHPIX moves        */
 | 
| +        /*   - the move is on a previously Y-touched point               */
 | 
| +
 | 
| +        if ( SUBPIXEL_HINTING   &&
 | 
| +             exc->ignore_x_mode )
 | 
|          {
 | 
|            /* save point for later comparison */
 | 
| -          if ( CUR.GS.freeVector.y != 0 )
 | 
| -            B1 = CUR.zp2.cur[point].y;
 | 
| +          if ( exc->GS.freeVector.y != 0 )
 | 
| +            B1 = exc->zp2.cur[point].y;
 | 
|            else
 | 
| -            B1 = CUR.zp2.cur[point].x;
 | 
| +            B1 = exc->zp2.cur[point].x;
 | 
|  
 | 
| -          if ( !CUR.face->sph_compatibility_mode &&
 | 
| -               CUR.GS.freeVector.y != 0          )
 | 
| +          if ( !exc->face->sph_compatibility_mode &&
 | 
| +               exc->GS.freeVector.y != 0          )
 | 
|            {
 | 
| -            MOVE_Zp2_Point( point, dx, dy, TRUE );
 | 
| +            Move_Zp2_Point( exc, point, dx, dy, TRUE );
 | 
|  
 | 
|              /* save new point */
 | 
| -            if ( CUR.GS.freeVector.y != 0 )
 | 
| +            if ( exc->GS.freeVector.y != 0 )
 | 
|              {
 | 
| -              B2 = CUR.zp2.cur[point].y;
 | 
| +              B2 = exc->zp2.cur[point].y;
 | 
|  
 | 
|                /* reverse any disallowed moves */
 | 
| -              if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
 | 
| -                   ( B1 & 63 ) != 0                                          &&
 | 
| -                   ( B2 & 63 ) != 0                                          &&
 | 
| -                    B1 != B2                                                 )
 | 
| -                MOVE_Zp2_Point( point, -dx, -dy, TRUE );
 | 
| +              if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
 | 
| +                   ( B1 & 63 ) != 0                                           &&
 | 
| +                   ( B2 & 63 ) != 0                                           &&
 | 
| +                   B1 != B2                                                   )
 | 
| +                Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
 | 
|              }
 | 
|            }
 | 
| -          else if ( CUR.face->sph_compatibility_mode )
 | 
| +          else if ( exc->face->sph_compatibility_mode )
 | 
|            {
 | 
| -            if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
 | 
| +            if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
 | 
|              {
 | 
|                dx = FT_PIX_ROUND( B1 + dx ) - B1;
 | 
|                dy = FT_PIX_ROUND( B1 + dy ) - B1;
 | 
|              }
 | 
|  
 | 
|              /* skip post-iup deltas */
 | 
| -            if ( CUR.iup_called                                          &&
 | 
| -                 ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
 | 
| -                   ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
 | 
| +            if ( exc->iup_called                                          &&
 | 
| +                 ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
 | 
| +                   ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
 | 
|                goto Skip;
 | 
|  
 | 
| -            if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
 | 
| -                  ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
 | 
| -                    ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )   ||
 | 
| -                    ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX )     )   )
 | 
| -              MOVE_Zp2_Point( point, 0, dy, TRUE );
 | 
| +            if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
 | 
| +                  ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
 | 
| +                    ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )    ||
 | 
| +                    ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX )      )  )
 | 
| +              Move_Zp2_Point( exc, point, 0, dy, TRUE );
 | 
|  
 | 
|              /* save new point */
 | 
| -            if ( CUR.GS.freeVector.y != 0 )
 | 
| +            if ( exc->GS.freeVector.y != 0 )
 | 
|              {
 | 
| -              B2 = CUR.zp2.cur[point].y;
 | 
| +              B2 = exc->zp2.cur[point].y;
 | 
|  
 | 
|                /* reverse any disallowed moves */
 | 
|                if ( ( B1 & 63 ) == 0 &&
 | 
|                     ( B2 & 63 ) != 0 &&
 | 
|                     B1 != B2         )
 | 
| -                MOVE_Zp2_Point( point, 0, -dy, TRUE );
 | 
| +                Move_Zp2_Point( exc, point, 0, -dy, TRUE );
 | 
|              }
 | 
|            }
 | 
| -          else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
 | 
| -            MOVE_Zp2_Point( point, dx, dy, TRUE );
 | 
| +          else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
 | 
| +            Move_Zp2_Point( exc, point, dx, dy, TRUE );
 | 
|          }
 | 
|          else
 | 
| -          MOVE_Zp2_Point( point, dx, dy, TRUE );
 | 
| +          Move_Zp2_Point( exc, point, dx, dy, TRUE );
 | 
|        }
 | 
|  
 | 
|      Skip:
 | 
|  
 | 
|  #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -        MOVE_Zp2_Point( point, dx, dy, TRUE );
 | 
| +      Move_Zp2_Point( exc, point, dx, dy, TRUE );
 | 
|  
 | 
|  #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -      CUR.GS.loop--;
 | 
| +      exc->GS.loop--;
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.loop = 1;
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->GS.loop = 1;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6247,7 +5785,8 @@
 | 
|    /* Stack:        f26.6 uint32 -->                                        */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MSIRP( INS_ARG )
 | 
| +  Ins_MSIRP( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   point;
 | 
|      FT_F26Dot6  distance;
 | 
| @@ -6258,11 +5797,11 @@
 | 
|  
 | 
|      if ( SUBPIXEL_HINTING )
 | 
|      {
 | 
| -      control_value_cutin = CUR.GS.control_value_cutin;
 | 
| +      control_value_cutin = exc->GS.control_value_cutin;
 | 
|  
 | 
| -      if ( CUR.ignore_x_mode                                 &&
 | 
| -           CUR.GS.freeVector.x != 0                          &&
 | 
| -           !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
| +      if ( exc->ignore_x_mode                                 &&
 | 
| +           exc->GS.freeVector.x != 0                          &&
 | 
| +           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
|          control_value_cutin = 0;
 | 
|      }
 | 
|  
 | 
| @@ -6270,42 +5809,41 @@
 | 
|  
 | 
|      point = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
 | 
| -         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( point,       exc->zp1.n_points ) ||
 | 
| +         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      /* UNDOCUMENTED!  The MS rasterizer does that with */
 | 
|      /* twilight points (confirmed by Greg Hitchcock)   */
 | 
| -    if ( CUR.GS.gep1 == 0 )
 | 
| +    if ( exc->GS.gep1 == 0 )
 | 
|      {
 | 
| -      CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
 | 
| -      CUR_Func_move_orig( &CUR.zp1, point, args[1] );
 | 
| -      CUR.zp1.cur[point] = CUR.zp1.org[point];
 | 
| +      exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
 | 
| +      exc->func_move_orig( exc, &exc->zp1, point, args[1] );
 | 
| +      exc->zp1.cur[point] = exc->zp1.org[point];
 | 
|      }
 | 
|  
 | 
| -    distance = CUR_Func_project( CUR.zp1.cur + point,
 | 
| -                                 CUR.zp0.cur + CUR.GS.rp0 );
 | 
| +    distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|      /* subpixel hinting - make MSIRP respect CVT cut-in; */
 | 
|      if ( SUBPIXEL_HINTING                                    &&
 | 
| -         CUR.ignore_x_mode                                   &&
 | 
| -         CUR.GS.freeVector.x != 0                            &&
 | 
| +         exc->ignore_x_mode                                  &&
 | 
| +         exc->GS.freeVector.x != 0                           &&
 | 
|           FT_ABS( distance - args[1] ) >= control_value_cutin )
 | 
|        distance = args[1];
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp1, point, args[1] - distance );
 | 
| +    exc->func_move( exc, &exc->zp1, point, args[1] - distance );
 | 
|  
 | 
| -    CUR.GS.rp1 = CUR.GS.rp0;
 | 
| -    CUR.GS.rp2 = point;
 | 
| +    exc->GS.rp1 = exc->GS.rp0;
 | 
| +    exc->GS.rp2 = point;
 | 
|  
 | 
| -    if ( ( CUR.opcode & 1 ) != 0 )
 | 
| -      CUR.GS.rp0 = point;
 | 
| +    if ( ( exc->opcode & 1 ) != 0 )
 | 
| +      exc->GS.rp0 = point;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6316,7 +5854,8 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MDAP( INS_ARG )
 | 
| +  Ins_MDAP( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   point;
 | 
|      FT_F26Dot6  cur_dist;
 | 
| @@ -6325,36 +5864,38 @@
 | 
|  
 | 
|      point = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( point, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( point, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    if ( ( CUR.opcode & 1 ) != 0 )
 | 
| +    if ( ( exc->opcode & 1 ) != 0 )
 | 
|      {
 | 
| -      cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
 | 
| +      cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -      if ( SUBPIXEL_HINTING         &&
 | 
| -           CUR.ignore_x_mode        &&
 | 
| -           CUR.GS.freeVector.x != 0 )
 | 
| -        distance = ROUND_None(
 | 
| +      if ( SUBPIXEL_HINTING          &&
 | 
| +           exc->ignore_x_mode        &&
 | 
| +           exc->GS.freeVector.x != 0 )
 | 
| +        distance = Round_None(
 | 
| +                     exc,
 | 
|                       cur_dist,
 | 
| -                     CUR.tt_metrics.compensations[0] ) - cur_dist;
 | 
| +                     exc->tt_metrics.compensations[0] ) - cur_dist;
 | 
|        else
 | 
|  #endif
 | 
| -        distance = CUR_Func_round(
 | 
| +        distance = exc->func_round(
 | 
| +                     exc,
 | 
|                       cur_dist,
 | 
| -                     CUR.tt_metrics.compensations[0] ) - cur_dist;
 | 
| +                     exc->tt_metrics.compensations[0] ) - cur_dist;
 | 
|      }
 | 
|      else
 | 
|        distance = 0;
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp0, point, distance );
 | 
| +    exc->func_move( exc, &exc->zp0, point, distance );
 | 
|  
 | 
| -    CUR.GS.rp0 = point;
 | 
| -    CUR.GS.rp1 = point;
 | 
| +    exc->GS.rp0 = point;
 | 
| +    exc->GS.rp1 = point;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6365,7 +5906,8 @@
 | 
|    /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MIAP( INS_ARG )
 | 
| +  Ins_MIAP( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      FT_ULong    cvtEntry;
 | 
|      FT_UShort   point;
 | 
| @@ -6374,24 +5916,24 @@
 | 
|      FT_F26Dot6  control_value_cutin;
 | 
|  
 | 
|  
 | 
| -    control_value_cutin = CUR.GS.control_value_cutin;
 | 
| +    control_value_cutin = exc->GS.control_value_cutin;
 | 
|      cvtEntry            = (FT_ULong)args[1];
 | 
|      point               = (FT_UShort)args[0];
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                  &&
 | 
| -         CUR.ignore_x_mode                                 &&
 | 
| -         CUR.GS.freeVector.x != 0                          &&
 | 
| -         CUR.GS.freeVector.y == 0                          &&
 | 
| -         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
| +    if ( SUBPIXEL_HINTING                                   &&
 | 
| +         exc->ignore_x_mode                                 &&
 | 
| +         exc->GS.freeVector.x != 0                          &&
 | 
| +         exc->GS.freeVector.y == 0                          &&
 | 
| +         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
|        control_value_cutin = 0;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    if ( BOUNDS( point,     CUR.zp0.n_points ) ||
 | 
| -         BOUNDSL( cvtEntry, CUR.cvtSize )      )
 | 
| +    if ( BOUNDS( point,     exc->zp0.n_points ) ||
 | 
| +         BOUNDSL( cvtEntry, exc->cvtSize )      )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
| @@ -6415,56 +5957,58 @@
 | 
|      /*                                                                    */
 | 
|      /* Confirmed by Greg Hitchcock.                                       */
 | 
|  
 | 
| -    distance = CUR_Func_read_cvt( cvtEntry );
 | 
| +    distance = exc->func_read_cvt( exc, cvtEntry );
 | 
|  
 | 
| -    if ( CUR.GS.gep0 == 0 )   /* If in twilight zone */
 | 
| +    if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
 | 
|      {
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|        /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
 | 
|        /* Determined via experimentation and may be incorrect...         */
 | 
| -      if ( !SUBPIXEL_HINTING                     ||
 | 
| -           ( !CUR.ignore_x_mode                ||
 | 
| -             !CUR.face->sph_compatibility_mode ) )
 | 
| +      if ( !SUBPIXEL_HINTING                      ||
 | 
| +           ( !exc->ignore_x_mode                ||
 | 
| +             !exc->face->sph_compatibility_mode ) )
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| -        CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
 | 
| -                                            CUR.GS.freeVector.x );
 | 
| -      CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
 | 
| -                                          CUR.GS.freeVector.y ),
 | 
| -      CUR.zp0.cur[point]   = CUR.zp0.org[point];
 | 
| +        exc->zp0.org[point].x = TT_MulFix14( distance,
 | 
| +                                             exc->GS.freeVector.x );
 | 
| +      exc->zp0.org[point].y = TT_MulFix14( distance,
 | 
| +                                           exc->GS.freeVector.y ),
 | 
| +      exc->zp0.cur[point]   = exc->zp0.org[point];
 | 
|      }
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                              &&
 | 
| -         CUR.ignore_x_mode                             &&
 | 
| -         ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
 | 
| -         distance > 0                                  &&
 | 
| -         CUR.GS.freeVector.y != 0                      )
 | 
| +    if ( SUBPIXEL_HINTING                               &&
 | 
| +         exc->ignore_x_mode                             &&
 | 
| +         ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
 | 
| +         distance > 0                                   &&
 | 
| +         exc->GS.freeVector.y != 0                      )
 | 
|        distance = 0;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
 | 
| +    org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 | 
|  
 | 
| -    if ( ( CUR.opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
 | 
| +    if ( ( exc->opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
 | 
|      {
 | 
|        if ( FT_ABS( distance - org_dist ) > control_value_cutin )
 | 
|          distance = org_dist;
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -      if ( SUBPIXEL_HINTING         &&
 | 
| -           CUR.ignore_x_mode        &&
 | 
| -           CUR.GS.freeVector.x != 0 )
 | 
| -        distance = ROUND_None( distance,
 | 
| -                               CUR.tt_metrics.compensations[0] );
 | 
| +      if ( SUBPIXEL_HINTING          &&
 | 
| +           exc->ignore_x_mode        &&
 | 
| +           exc->GS.freeVector.x != 0 )
 | 
| +        distance = Round_None( exc,
 | 
| +                               distance,
 | 
| +                               exc->tt_metrics.compensations[0] );
 | 
|        else
 | 
|  #endif
 | 
| -        distance = CUR_Func_round( distance,
 | 
| -                                   CUR.tt_metrics.compensations[0] );
 | 
| +        distance = exc->func_round( exc,
 | 
| +                                    distance,
 | 
| +                                    exc->tt_metrics.compensations[0] );
 | 
|      }
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp0, point, distance - org_dist );
 | 
| +    exc->func_move( exc, &exc->zp0, point, distance - org_dist );
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.rp0 = point;
 | 
| -    CUR.GS.rp1 = point;
 | 
| +    exc->GS.rp0 = point;
 | 
| +    exc->GS.rp1 = point;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6475,29 +6019,30 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MDRP( INS_ARG )
 | 
| +  Ins_MDRP( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   point;
 | 
|      FT_F26Dot6  org_dist, distance, minimum_distance;
 | 
|  
 | 
|  
 | 
| -    minimum_distance = CUR.GS.minimum_distance;
 | 
| +    minimum_distance = exc->GS.minimum_distance;
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                  &&
 | 
| -         CUR.ignore_x_mode                                 &&
 | 
| -         CUR.GS.freeVector.x != 0                          &&
 | 
| -         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
| +    if ( SUBPIXEL_HINTING                                   &&
 | 
| +         exc->ignore_x_mode                                 &&
 | 
| +         exc->GS.freeVector.x != 0                          &&
 | 
| +         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
|        minimum_distance = 0;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|      point = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
 | 
| -         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( point,       exc->zp1.n_points ) ||
 | 
| +         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
| @@ -6506,74 +6051,77 @@
 | 
|  
 | 
|      /* XXX: UNDOCUMENTED: twilight zone special case */
 | 
|  
 | 
| -    if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
 | 
| +    if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
 | 
|      {
 | 
| -      FT_Vector*  vec1 = &CUR.zp1.org[point];
 | 
| -      FT_Vector*  vec2 = &CUR.zp0.org[CUR.GS.rp0];
 | 
| +      FT_Vector*  vec1 = &exc->zp1.org[point];
 | 
| +      FT_Vector*  vec2 = &exc->zp0.org[exc->GS.rp0];
 | 
|  
 | 
|  
 | 
| -      org_dist = CUR_Func_dualproj( vec1, vec2 );
 | 
| +      org_dist = DUALPROJ( vec1, vec2 );
 | 
|      }
 | 
|      else
 | 
|      {
 | 
| -      FT_Vector*  vec1 = &CUR.zp1.orus[point];
 | 
| -      FT_Vector*  vec2 = &CUR.zp0.orus[CUR.GS.rp0];
 | 
| +      FT_Vector*  vec1 = &exc->zp1.orus[point];
 | 
| +      FT_Vector*  vec2 = &exc->zp0.orus[exc->GS.rp0];
 | 
|  
 | 
|  
 | 
| -      if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
 | 
| +      if ( exc->metrics.x_scale == exc->metrics.y_scale )
 | 
|        {
 | 
|          /* this should be faster */
 | 
| -        org_dist = CUR_Func_dualproj( vec1, vec2 );
 | 
| -        org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
 | 
| +        org_dist = DUALPROJ( vec1, vec2 );
 | 
| +        org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
 | 
|        }
 | 
|        else
 | 
|        {
 | 
|          FT_Vector  vec;
 | 
|  
 | 
|  
 | 
| -        vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
 | 
| -        vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
 | 
| +        vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
 | 
| +        vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 | 
|  
 | 
| -        org_dist = CUR_fast_dualproj( &vec );
 | 
| +        org_dist = FAST_DUALPROJ( &vec );
 | 
|        }
 | 
|      }
 | 
|  
 | 
|      /* single width cut-in test */
 | 
|  
 | 
| -    if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <
 | 
| -         CUR.GS.single_width_cutin )
 | 
| +    if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
 | 
| +         exc->GS.single_width_cutin )
 | 
|      {
 | 
|        if ( org_dist >= 0 )
 | 
| -        org_dist = CUR.GS.single_width_value;
 | 
| +        org_dist = exc->GS.single_width_value;
 | 
|        else
 | 
| -        org_dist = -CUR.GS.single_width_value;
 | 
| +        org_dist = -exc->GS.single_width_value;
 | 
|      }
 | 
|  
 | 
|      /* round flag */
 | 
|  
 | 
| -    if ( ( CUR.opcode & 4 ) != 0 )
 | 
| +    if ( ( exc->opcode & 4 ) != 0 )
 | 
|      {
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -      if ( SUBPIXEL_HINTING         &&
 | 
| -           CUR.ignore_x_mode        &&
 | 
| -           CUR.GS.freeVector.x != 0 )
 | 
| -        distance = ROUND_None(
 | 
| +      if ( SUBPIXEL_HINTING          &&
 | 
| +           exc->ignore_x_mode        &&
 | 
| +           exc->GS.freeVector.x != 0 )
 | 
| +        distance = Round_None(
 | 
| +                     exc,
 | 
|                       org_dist,
 | 
| -                     CUR.tt_metrics.compensations[CUR.opcode & 3] );
 | 
| +                     exc->tt_metrics.compensations[exc->opcode & 3] );
 | 
|        else
 | 
|  #endif
 | 
| -      distance = CUR_Func_round(
 | 
| -                   org_dist,
 | 
| -                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
 | 
| +        distance = exc->func_round(
 | 
| +                     exc,
 | 
| +                     org_dist,
 | 
| +                     exc->tt_metrics.compensations[exc->opcode & 3] );
 | 
|      }
 | 
|      else
 | 
| -      distance = ROUND_None(
 | 
| +      distance = Round_None(
 | 
| +                   exc,
 | 
|                     org_dist,
 | 
| -                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
 | 
| +                   exc->tt_metrics.compensations[exc->opcode & 3] );
 | 
|  
 | 
|      /* minimum distance flag */
 | 
|  
 | 
| -    if ( ( CUR.opcode & 8 ) != 0 )
 | 
| +    if ( ( exc->opcode & 8 ) != 0 )
 | 
|      {
 | 
|        if ( org_dist >= 0 )
 | 
|        {
 | 
| @@ -6589,17 +6137,16 @@
 | 
|  
 | 
|      /* now move the point */
 | 
|  
 | 
| -    org_dist = CUR_Func_project( CUR.zp1.cur + point,
 | 
| -                                 CUR.zp0.cur + CUR.GS.rp0 );
 | 
| +    org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp1, point, distance - org_dist );
 | 
| +    exc->func_move( exc, &exc->zp1, point, distance - org_dist );
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.rp1 = CUR.GS.rp0;
 | 
| -    CUR.GS.rp2 = point;
 | 
| +    exc->GS.rp1 = exc->GS.rp0;
 | 
| +    exc->GS.rp2 = point;
 | 
|  
 | 
| -    if ( ( CUR.opcode & 16 ) != 0 )
 | 
| -      CUR.GS.rp0 = point;
 | 
| +    if ( ( exc->opcode & 16 ) != 0 )
 | 
| +      exc->GS.rp0 = point;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6610,7 +6157,8 @@
 | 
|    /* Stack:        int32? uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_MIRP( INS_ARG )
 | 
| +  Ins_MIRP( TT_ExecContext  exc,
 | 
| +            FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   point;
 | 
|      FT_ULong    cvtEntry;
 | 
| @@ -6628,77 +6176,75 @@
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|  
 | 
| -    minimum_distance    = CUR.GS.minimum_distance;
 | 
| -    control_value_cutin = CUR.GS.control_value_cutin;
 | 
| +    minimum_distance    = exc->GS.minimum_distance;
 | 
| +    control_value_cutin = exc->GS.control_value_cutin;
 | 
|      point               = (FT_UShort)args[0];
 | 
|      cvtEntry            = (FT_ULong)( args[1] + 1 );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                  &&
 | 
| -         CUR.ignore_x_mode                                 &&
 | 
| -         CUR.GS.freeVector.x != 0                          &&
 | 
| -         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
| +    if ( SUBPIXEL_HINTING                                   &&
 | 
| +         exc->ignore_x_mode                                 &&
 | 
| +         exc->GS.freeVector.x != 0                          &&
 | 
| +         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
 | 
|        control_value_cutin = minimum_distance = 0;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|      /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
 | 
|  
 | 
| -    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
 | 
| -         BOUNDSL( cvtEntry,  CUR.cvtSize + 1 )  ||
 | 
| -         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( point,       exc->zp1.n_points ) ||
 | 
| +         BOUNDSL( cvtEntry,   exc->cvtSize + 1 )  ||
 | 
| +         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
|      if ( !cvtEntry )
 | 
|        cvt_dist = 0;
 | 
|      else
 | 
| -      cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
 | 
| +      cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
 | 
|  
 | 
|      /* single width test */
 | 
|  
 | 
| -    if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
 | 
| -         CUR.GS.single_width_cutin )
 | 
| +    if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
 | 
| +         exc->GS.single_width_cutin )
 | 
|      {
 | 
|        if ( cvt_dist >= 0 )
 | 
| -        cvt_dist =  CUR.GS.single_width_value;
 | 
| +        cvt_dist =  exc->GS.single_width_value;
 | 
|        else
 | 
| -        cvt_dist = -CUR.GS.single_width_value;
 | 
| +        cvt_dist = -exc->GS.single_width_value;
 | 
|      }
 | 
|  
 | 
|      /* UNDOCUMENTED!  The MS rasterizer does that with */
 | 
|      /* twilight points (confirmed by Greg Hitchcock)   */
 | 
| -    if ( CUR.GS.gep1 == 0 )
 | 
| +    if ( exc->GS.gep1 == 0 )
 | 
|      {
 | 
| -      CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
 | 
| -                             TT_MulFix14( (FT_UInt32)cvt_dist,
 | 
| -                                          CUR.GS.freeVector.x );
 | 
| -      CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
 | 
| -                             TT_MulFix14( (FT_UInt32)cvt_dist,
 | 
| -                                          CUR.GS.freeVector.y );
 | 
| -      CUR.zp1.cur[point]   = CUR.zp1.org[point];
 | 
| +      exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
 | 
| +                              TT_MulFix14( cvt_dist,
 | 
| +                                           exc->GS.freeVector.x );
 | 
| +      exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
 | 
| +                              TT_MulFix14( cvt_dist,
 | 
| +                                           exc->GS.freeVector.y );
 | 
| +      exc->zp1.cur[point]   = exc->zp1.org[point];
 | 
|      }
 | 
|  
 | 
| -    org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
 | 
| -                                  &CUR.zp0.org[CUR.GS.rp0] );
 | 
| -    cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
 | 
| -                                  &CUR.zp0.cur[CUR.GS.rp0] );
 | 
| +    org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
 | 
| +    cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
 | 
|  
 | 
|      /* auto-flip test */
 | 
|  
 | 
| -    if ( CUR.GS.auto_flip )
 | 
| +    if ( exc->GS.auto_flip )
 | 
|      {
 | 
|        if ( ( org_dist ^ cvt_dist ) < 0 )
 | 
|          cvt_dist = -cvt_dist;
 | 
|      }
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                         &&
 | 
| -         CUR.ignore_x_mode                                        &&
 | 
| -         CUR.GS.freeVector.y != 0                                 &&
 | 
| -         ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
 | 
| +    if ( SUBPIXEL_HINTING                                          &&
 | 
| +         exc->ignore_x_mode                                        &&
 | 
| +         exc->GS.freeVector.y != 0                                 &&
 | 
| +         ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
 | 
|      {
 | 
|        if ( cur_dist < -64 )
 | 
|          cvt_dist -= 16;
 | 
| @@ -6709,12 +6255,12 @@
 | 
|  
 | 
|      /* control value cut-in and round */
 | 
|  
 | 
| -    if ( ( CUR.opcode & 4 ) != 0 )
 | 
| +    if ( ( exc->opcode & 4 ) != 0 )
 | 
|      {
 | 
|        /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */
 | 
|        /*      refer to the same zone.                                  */
 | 
|  
 | 
| -      if ( CUR.GS.gep0 == CUR.GS.gep1 )
 | 
| +      if ( exc->GS.gep0 == exc->GS.gep1 )
 | 
|        {
 | 
|          /* XXX: According to Greg Hitchcock, the following wording is */
 | 
|          /*      the right one:                                        */
 | 
| @@ -6732,32 +6278,34 @@
 | 
|            cvt_dist = org_dist;
 | 
|        }
 | 
|  
 | 
| -      distance = CUR_Func_round(
 | 
| +      distance = exc->func_round(
 | 
| +                   exc,
 | 
|                     cvt_dist,
 | 
| -                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
 | 
| +                   exc->tt_metrics.compensations[exc->opcode & 3] );
 | 
|      }
 | 
|      else
 | 
|      {
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|        /* do cvt cut-in always in MIRP for sph */
 | 
| -      if ( SUBPIXEL_HINTING           &&
 | 
| -           CUR.ignore_x_mode          &&
 | 
| -           CUR.GS.gep0 == CUR.GS.gep1 )
 | 
| +      if ( SUBPIXEL_HINTING             &&
 | 
| +           exc->ignore_x_mode           &&
 | 
| +           exc->GS.gep0 == exc->GS.gep1 )
 | 
|        {
 | 
|          if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
 | 
|            cvt_dist = org_dist;
 | 
|        }
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -      distance = ROUND_None(
 | 
| +      distance = Round_None(
 | 
| +                   exc,
 | 
|                     cvt_dist,
 | 
| -                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
 | 
| +                   exc->tt_metrics.compensations[exc->opcode & 3] );
 | 
|      }
 | 
|  
 | 
|      /* minimum distance test */
 | 
|  
 | 
| -    if ( ( CUR.opcode & 8 ) != 0 )
 | 
| +    if ( ( exc->opcode & 8 ) != 0 )
 | 
|      {
 | 
|        if ( org_dist >= 0 )
 | 
|        {
 | 
| @@ -6774,59 +6322,59 @@
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|      if ( SUBPIXEL_HINTING )
 | 
|      {
 | 
| -      B1 = CUR.zp1.cur[point].y;
 | 
| +      B1 = exc->zp1.cur[point].y;
 | 
|  
 | 
|        /* Round moves if necessary */
 | 
| -      if ( CUR.ignore_x_mode                                          &&
 | 
| -           CUR.GS.freeVector.y != 0                                   &&
 | 
| -           ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
 | 
| +      if ( exc->ignore_x_mode                                          &&
 | 
| +           exc->GS.freeVector.y != 0                                   &&
 | 
| +           ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
 | 
|          distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
 | 
|  
 | 
| -      if ( CUR.ignore_x_mode                                      &&
 | 
| -           CUR.GS.freeVector.y != 0                               &&
 | 
| -           ( CUR.opcode & 16 ) == 0                               &&
 | 
| -           ( CUR.opcode & 8 ) == 0                                &&
 | 
| -           ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
 | 
| +      if ( exc->ignore_x_mode                                      &&
 | 
| +           exc->GS.freeVector.y != 0                               &&
 | 
| +           ( exc->opcode & 16 ) == 0                               &&
 | 
| +           ( exc->opcode & 8 ) == 0                                &&
 | 
| +           ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
 | 
|          distance += 64;
 | 
|      }
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
 | 
| +    exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|      if ( SUBPIXEL_HINTING )
 | 
|      {
 | 
| -      B2 = CUR.zp1.cur[point].y;
 | 
| +      B2 = exc->zp1.cur[point].y;
 | 
|  
 | 
|        /* Reverse move if necessary */
 | 
| -      if ( CUR.ignore_x_mode )
 | 
| +      if ( exc->ignore_x_mode )
 | 
|        {
 | 
| -        if ( CUR.face->sph_compatibility_mode                          &&
 | 
| -             CUR.GS.freeVector.y != 0                                  &&
 | 
| -             ( B1 & 63 ) == 0                                          &&
 | 
| -             ( B2 & 63 ) != 0                                          )
 | 
| +        if ( exc->face->sph_compatibility_mode &&
 | 
| +             exc->GS.freeVector.y != 0         &&
 | 
| +             ( B1 & 63 ) == 0                  &&
 | 
| +             ( B2 & 63 ) != 0                  )
 | 
|            reverse_move = TRUE;
 | 
|  
 | 
| -        if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
 | 
| -             CUR.GS.freeVector.y != 0                                  &&
 | 
| -             ( B2 & 63 ) != 0                                          &&
 | 
| -             ( B1 & 63 ) != 0                                          )
 | 
| +        if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
 | 
| +             exc->GS.freeVector.y != 0                                  &&
 | 
| +             ( B2 & 63 ) != 0                                           &&
 | 
| +             ( B1 & 63 ) != 0                                           )
 | 
|            reverse_move = TRUE;
 | 
|        }
 | 
|  
 | 
|        if ( reverse_move )
 | 
| -        CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
 | 
| +        exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
 | 
|      }
 | 
|  
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.rp1 = CUR.GS.rp0;
 | 
| +    exc->GS.rp1 = exc->GS.rp0;
 | 
|  
 | 
| -    if ( ( CUR.opcode & 16 ) != 0 )
 | 
| -      CUR.GS.rp0 = point;
 | 
| +    if ( ( exc->opcode & 16 ) != 0 )
 | 
| +      exc->GS.rp0 = point;
 | 
|  
 | 
| -    CUR.GS.rp2 = point;
 | 
| +    exc->GS.rp2 = point;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6837,61 +6385,59 @@
 | 
|    /* Stack:        uint32 uint32... -->                                    */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_ALIGNRP( INS_ARG )
 | 
| +  Ins_ALIGNRP( TT_ExecContext  exc )
 | 
|    {
 | 
|      FT_UShort   point;
 | 
|      FT_F26Dot6  distance;
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
| -
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING                                         &&
 | 
| -         CUR.ignore_x_mode                                        &&
 | 
| -         CUR.iup_called                                           &&
 | 
| -         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
 | 
| +    if ( SUBPIXEL_HINTING                                          &&
 | 
| +         exc->ignore_x_mode                                        &&
 | 
| +         exc->iup_called                                           &&
 | 
| +         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
 | 
|      {
 | 
| -      CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -    if ( CUR.top < CUR.GS.loop ||
 | 
| -         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
 | 
| +    if ( exc->top < exc->GS.loop                  ||
 | 
| +         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
| -    while ( CUR.GS.loop > 0 )
 | 
| +    while ( exc->GS.loop > 0 )
 | 
|      {
 | 
| -      CUR.args--;
 | 
| +      exc->args--;
 | 
|  
 | 
| -      point = (FT_UShort)CUR.stack[CUR.args];
 | 
| +      point = (FT_UShort)exc->stack[exc->args];
 | 
|  
 | 
| -      if ( BOUNDS( point, CUR.zp1.n_points ) )
 | 
| +      if ( BOUNDS( point, exc->zp1.n_points ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|        }
 | 
|        else
 | 
|        {
 | 
| -        distance = CUR_Func_project( CUR.zp1.cur + point,
 | 
| -                                     CUR.zp0.cur + CUR.GS.rp0 );
 | 
| +        distance = PROJECT( exc->zp1.cur + point,
 | 
| +                            exc->zp0.cur + exc->GS.rp0 );
 | 
|  
 | 
| -        CUR_Func_move( &CUR.zp1, point, -distance );
 | 
| +        exc->func_move( exc, &exc->zp1, point, -distance );
 | 
|        }
 | 
|  
 | 
| -      CUR.GS.loop--;
 | 
| +      exc->GS.loop--;
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.loop = 1;
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->GS.loop = 1;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6902,7 +6448,8 @@
 | 
|    /* Stack:        5 * uint32 -->                                          */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_ISECT( INS_ARG )
 | 
| +  Ins_ISECT( TT_ExecContext  exc,
 | 
| +             FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   point,
 | 
|                  a0, a1,
 | 
| @@ -6926,29 +6473,27 @@
 | 
|      b0 = (FT_UShort)args[3];
 | 
|      b1 = (FT_UShort)args[4];
 | 
|  
 | 
| -    if ( BOUNDS( b0, CUR.zp0.n_points )  ||
 | 
| -         BOUNDS( b1, CUR.zp0.n_points )  ||
 | 
| -         BOUNDS( a0, CUR.zp1.n_points )  ||
 | 
| -         BOUNDS( a1, CUR.zp1.n_points )  ||
 | 
| -         BOUNDS( point, CUR.zp2.n_points ) )
 | 
| +    if ( BOUNDS( b0,    exc->zp0.n_points ) ||
 | 
| +         BOUNDS( b1,    exc->zp0.n_points ) ||
 | 
| +         BOUNDS( a0,    exc->zp1.n_points ) ||
 | 
| +         BOUNDS( a1,    exc->zp1.n_points ) ||
 | 
| +         BOUNDS( point, exc->zp2.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      /* Cramer's rule */
 | 
|  
 | 
| -    dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
 | 
| -    dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
 | 
| +    dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
 | 
| +    dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
 | 
|  
 | 
| -    dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
 | 
| -    day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
 | 
| +    dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
 | 
| +    day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
 | 
|  
 | 
| -    dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
 | 
| -    dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
 | 
| -
 | 
| -    CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
 | 
| +    dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
 | 
| +    dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
 | 
|  
 | 
|      discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
 | 
|                     FT_MulDiv( day, dbx, 0x40 );
 | 
| @@ -6970,22 +6515,24 @@
 | 
|        R.x = FT_MulDiv( val, dax, discriminant );
 | 
|        R.y = FT_MulDiv( val, day, discriminant );
 | 
|  
 | 
| -      CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
 | 
| -      CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
 | 
| +      exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
 | 
| +      exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
|        /* else, take the middle of the middles of A and B */
 | 
|  
 | 
| -      CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
 | 
| -                               CUR.zp1.cur[a1].x +
 | 
| -                               CUR.zp0.cur[b0].x +
 | 
| -                               CUR.zp0.cur[b1].x ) / 4;
 | 
| -      CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
 | 
| -                               CUR.zp1.cur[a1].y +
 | 
| -                               CUR.zp0.cur[b0].y +
 | 
| -                               CUR.zp0.cur[b1].y ) / 4;
 | 
| +      exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
 | 
| +                                exc->zp1.cur[a1].x +
 | 
| +                                exc->zp0.cur[b0].x +
 | 
| +                                exc->zp0.cur[b1].x ) / 4;
 | 
| +      exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
 | 
| +                                exc->zp1.cur[a1].y +
 | 
| +                                exc->zp0.cur[b0].y +
 | 
| +                                exc->zp0.cur[b1].y ) / 4;
 | 
|      }
 | 
| +
 | 
| +    exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -6996,7 +6543,8 @@
 | 
|    /* Stack:        uint32 uint32 -->                                       */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_ALIGNPTS( INS_ARG )
 | 
| +  Ins_ALIGNPTS( TT_ExecContext  exc,
 | 
| +                FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort   p1, p2;
 | 
|      FT_F26Dot6  distance;
 | 
| @@ -7005,19 +6553,18 @@
 | 
|      p1 = (FT_UShort)args[0];
 | 
|      p2 = (FT_UShort)args[1];
 | 
|  
 | 
| -    if ( BOUNDS( p1, CUR.zp1.n_points ) ||
 | 
| -         BOUNDS( p2, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( p1, exc->zp1.n_points ) ||
 | 
| +         BOUNDS( p2, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    distance = CUR_Func_project( CUR.zp0.cur + p2,
 | 
| -                                 CUR.zp1.cur + p1 ) / 2;
 | 
| +    distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
 | 
|  
 | 
| -    CUR_Func_move( &CUR.zp1, p1, distance );
 | 
| -    CUR_Func_move( &CUR.zp0, p2, -distance );
 | 
| +    exc->func_move( exc, &exc->zp1, p1, distance );
 | 
| +    exc->func_move( exc, &exc->zp0, p2, -distance );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7031,50 +6578,48 @@
 | 
|    /* SOMETIMES, DUMBER CODE IS BETTER CODE */
 | 
|  
 | 
|    static void
 | 
| -  Ins_IP( INS_ARG )
 | 
| +  Ins_IP( TT_ExecContext  exc )
 | 
|    {
 | 
|      FT_F26Dot6  old_range, cur_range;
 | 
|      FT_Vector*  orus_base;
 | 
|      FT_Vector*  cur_base;
 | 
|      FT_Int      twilight;
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
|  
 | 
| -
 | 
| -    if ( CUR.top < CUR.GS.loop )
 | 
| +    if ( exc->top < exc->GS.loop )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
|      /*
 | 
|       * We need to deal in a special way with the twilight zone.
 | 
| -     * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
 | 
| +     * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
 | 
|       * for every n.
 | 
|       */
 | 
| -    twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
 | 
| +    twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
 | 
|  
 | 
| -    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        goto Fail;
 | 
|      }
 | 
|  
 | 
|      if ( twilight )
 | 
| -      orus_base = &CUR.zp0.org[CUR.GS.rp1];
 | 
| +      orus_base = &exc->zp0.org[exc->GS.rp1];
 | 
|      else
 | 
| -      orus_base = &CUR.zp0.orus[CUR.GS.rp1];
 | 
| +      orus_base = &exc->zp0.orus[exc->GS.rp1];
 | 
|  
 | 
| -    cur_base = &CUR.zp0.cur[CUR.GS.rp1];
 | 
| +    cur_base = &exc->zp0.cur[exc->GS.rp1];
 | 
|  
 | 
|      /* XXX: There are some glyphs in some braindead but popular */
 | 
|      /*      fonts out there (e.g. [aeu]grave in monotype.ttf)   */
 | 
|      /*      calling IP[] with bad values of rp[12].             */
 | 
|      /*      Do something sane when this odd thing happens.      */
 | 
| -    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
 | 
| -         BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
 | 
| +    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
 | 
| +         BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
 | 
|      {
 | 
|        old_range = 0;
 | 
|        cur_range = 0;
 | 
| @@ -7082,62 +6627,60 @@
 | 
|      else
 | 
|      {
 | 
|        if ( twilight )
 | 
| -        old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
 | 
| -                                       orus_base );
 | 
| -      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
 | 
| -        old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
 | 
| -                                       orus_base );
 | 
| +        old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base );
 | 
| +      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
 | 
| +        old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base );
 | 
|        else
 | 
|        {
 | 
|          FT_Vector  vec;
 | 
|  
 | 
|  
 | 
| -        vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
 | 
| -                           CUR.metrics.x_scale );
 | 
| -        vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
 | 
| -                           CUR.metrics.y_scale );
 | 
| +        vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
 | 
| +                           exc->metrics.x_scale );
 | 
| +        vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
 | 
| +                           exc->metrics.y_scale );
 | 
|  
 | 
| -        old_range = CUR_fast_dualproj( &vec );
 | 
| +        old_range = FAST_DUALPROJ( &vec );
 | 
|        }
 | 
|  
 | 
| -      cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
 | 
| +      cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
 | 
|      }
 | 
|  
 | 
| -    for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
 | 
| +    for ( ; exc->GS.loop > 0; --exc->GS.loop )
 | 
|      {
 | 
| -      FT_UInt     point = (FT_UInt)CUR.stack[--CUR.args];
 | 
| +      FT_UInt     point = (FT_UInt)exc->stack[--exc->args];
 | 
|        FT_F26Dot6  org_dist, cur_dist, new_dist;
 | 
|  
 | 
|  
 | 
|        /* check point bounds */
 | 
| -      if ( BOUNDS( point, CUR.zp2.n_points ) )
 | 
| +      if ( BOUNDS( point, exc->zp2.n_points ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|          continue;
 | 
|        }
 | 
|  
 | 
|        if ( twilight )
 | 
| -        org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
 | 
| -      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
 | 
| -        org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
 | 
| +        org_dist = DUALPROJ( &exc->zp2.org[point], orus_base );
 | 
| +      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
 | 
| +        org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base );
 | 
|        else
 | 
|        {
 | 
|          FT_Vector  vec;
 | 
|  
 | 
|  
 | 
| -        vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
 | 
| -                           CUR.metrics.x_scale );
 | 
| -        vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
 | 
| -                           CUR.metrics.y_scale );
 | 
| +        vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
 | 
| +                           exc->metrics.x_scale );
 | 
| +        vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
 | 
| +                           exc->metrics.y_scale );
 | 
|  
 | 
| -        org_dist = CUR_fast_dualproj( &vec );
 | 
| +        org_dist = FAST_DUALPROJ( &vec );
 | 
|        }
 | 
|  
 | 
| -      cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
 | 
| +      cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
 | 
|  
 | 
|        if ( org_dist )
 | 
|        {
 | 
| @@ -7167,12 +6710,15 @@
 | 
|        else
 | 
|          new_dist = 0;
 | 
|  
 | 
| -      CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
 | 
| +      exc->func_move( exc,
 | 
| +                      &exc->zp2,
 | 
| +                      (FT_UShort)point,
 | 
| +                      new_dist - cur_dist );
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.GS.loop = 1;
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->GS.loop = 1;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7183,7 +6729,8 @@
 | 
|    /* Stack:        uint32 -->                                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_UTP( INS_ARG )
 | 
| +  Ins_UTP( TT_ExecContext  exc,
 | 
| +           FT_Long*        args )
 | 
|    {
 | 
|      FT_UShort  point;
 | 
|      FT_Byte    mask;
 | 
| @@ -7191,22 +6738,22 @@
 | 
|  
 | 
|      point = (FT_UShort)args[0];
 | 
|  
 | 
| -    if ( BOUNDS( point, CUR.zp0.n_points ) )
 | 
| +    if ( BOUNDS( point, exc->zp0.n_points ) )
 | 
|      {
 | 
| -      if ( CUR.pedantic_hinting )
 | 
| -        CUR.error = FT_THROW( Invalid_Reference );
 | 
| +      if ( exc->pedantic_hinting )
 | 
| +        exc->error = FT_THROW( Invalid_Reference );
 | 
|        return;
 | 
|      }
 | 
|  
 | 
|      mask = 0xFF;
 | 
|  
 | 
| -    if ( CUR.GS.freeVector.x != 0 )
 | 
| +    if ( exc->GS.freeVector.x != 0 )
 | 
|        mask &= ~FT_CURVE_TAG_TOUCH_X;
 | 
|  
 | 
| -    if ( CUR.GS.freeVector.y != 0 )
 | 
| +    if ( exc->GS.freeVector.y != 0 )
 | 
|        mask &= ~FT_CURVE_TAG_TOUCH_Y;
 | 
|  
 | 
| -    CUR.zp0.tags[point] &= mask;
 | 
| +    exc->zp0.tags[point] &= mask;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7251,7 +6798,7 @@
 | 
|                             FT_UInt     ref2 )
 | 
|    {
 | 
|      FT_UInt     i;
 | 
| -    FT_F26Dot6  orus1, orus2, org1, org2, delta1, delta2;
 | 
| +    FT_F26Dot6  orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
 | 
|  
 | 
|  
 | 
|      if ( p1 > p2 )
 | 
| @@ -7281,12 +6828,15 @@
 | 
|  
 | 
|      org1   = worker->orgs[ref1].x;
 | 
|      org2   = worker->orgs[ref2].x;
 | 
| -    delta1 = worker->curs[ref1].x - org1;
 | 
| -    delta2 = worker->curs[ref2].x - org2;
 | 
| +    cur1   = worker->curs[ref1].x;
 | 
| +    cur2   = worker->curs[ref2].x;
 | 
| +    delta1 = cur1 - org1;
 | 
| +    delta2 = cur2 - org2;
 | 
|  
 | 
| -    if ( orus1 == orus2 )
 | 
| +    if ( cur1 == cur2 || orus1 == orus2 )
 | 
|      {
 | 
| -      /* simple shift of untouched points */
 | 
| +
 | 
| +      /* trivial snap or shift of untouched points */
 | 
|        for ( i = p1; i <= p2; i++ )
 | 
|        {
 | 
|          FT_F26Dot6  x = worker->orgs[i].x;
 | 
| @@ -7294,9 +6844,13 @@
 | 
|  
 | 
|          if ( x <= org1 )
 | 
|            x += delta1;
 | 
| -        else
 | 
| +
 | 
| +        else if ( x >= org2 )
 | 
|            x += delta2;
 | 
|  
 | 
| +        else
 | 
| +          x = cur1;
 | 
| +
 | 
|          worker->curs[i].x = x;
 | 
|        }
 | 
|      }
 | 
| @@ -7323,12 +6877,10 @@
 | 
|            if ( !scale_valid )
 | 
|            {
 | 
|              scale_valid = 1;
 | 
| -            scale       = FT_DivFix( org2 + delta2 - ( org1 + delta1 ),
 | 
| -                                     orus2 - orus1 );
 | 
| +            scale       = FT_DivFix( cur2 - cur1, orus2 - orus1 );
 | 
|            }
 | 
|  
 | 
| -          x = ( org1 + delta1 ) +
 | 
| -              FT_MulFix( worker->orus[i].x - orus1, scale );
 | 
| +          x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
 | 
|          }
 | 
|          worker->curs[i].x = x;
 | 
|        }
 | 
| @@ -7343,7 +6895,7 @@
 | 
|    /* Stack:        -->                                                     */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_IUP( INS_ARG )
 | 
| +  Ins_IUP( TT_ExecContext  exc )
 | 
|    {
 | 
|      IUP_WorkerRec  V;
 | 
|      FT_Byte        mask;
 | 
| @@ -7357,51 +6909,49 @@
 | 
|      FT_UInt   point;         /* current point   */
 | 
|      FT_Short  contour;       /* current contour */
 | 
|  
 | 
| -    FT_UNUSED_ARG;
 | 
| -
 | 
|  
 | 
|      /* ignore empty outlines */
 | 
| -    if ( CUR.pts.n_contours == 0 )
 | 
| +    if ( exc->pts.n_contours == 0 )
 | 
|        return;
 | 
|  
 | 
| -    if ( CUR.opcode & 1 )
 | 
| +    if ( exc->opcode & 1 )
 | 
|      {
 | 
|        mask   = FT_CURVE_TAG_TOUCH_X;
 | 
| -      V.orgs = CUR.pts.org;
 | 
| -      V.curs = CUR.pts.cur;
 | 
| -      V.orus = CUR.pts.orus;
 | 
| +      V.orgs = exc->pts.org;
 | 
| +      V.curs = exc->pts.cur;
 | 
| +      V.orus = exc->pts.orus;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
|        mask   = FT_CURVE_TAG_TOUCH_Y;
 | 
| -      V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );
 | 
| -      V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
 | 
| -      V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
 | 
| +      V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
 | 
| +      V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
 | 
| +      V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
 | 
|      }
 | 
| -    V.max_points = CUR.pts.n_points;
 | 
| +    V.max_points = exc->pts.n_points;
 | 
|  
 | 
|      contour = 0;
 | 
|      point   = 0;
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    if ( SUBPIXEL_HINTING  &&
 | 
| -         CUR.ignore_x_mode )
 | 
| +    if ( SUBPIXEL_HINTING   &&
 | 
| +         exc->ignore_x_mode )
 | 
|      {
 | 
| -      CUR.iup_called = TRUE;
 | 
| -      if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
 | 
| +      exc->iup_called = TRUE;
 | 
| +      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
 | 
|          return;
 | 
|      }
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|      do
 | 
|      {
 | 
| -      end_point   = CUR.pts.contours[contour] - CUR.pts.first_point;
 | 
| +      end_point   = exc->pts.contours[contour] - exc->pts.first_point;
 | 
|        first_point = point;
 | 
|  
 | 
| -      if ( BOUNDS ( end_point, CUR.pts.n_points ) )
 | 
| -        end_point = CUR.pts.n_points - 1;
 | 
| +      if ( BOUNDS( end_point, exc->pts.n_points ) )
 | 
| +        end_point = exc->pts.n_points - 1;
 | 
|  
 | 
| -      while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
 | 
| +      while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
 | 
|          point++;
 | 
|  
 | 
|        if ( point <= end_point )
 | 
| @@ -7413,7 +6963,7 @@
 | 
|  
 | 
|          while ( point <= end_point )
 | 
|          {
 | 
| -          if ( ( CUR.pts.tags[point] & mask ) != 0 )
 | 
| +          if ( ( exc->pts.tags[point] & mask ) != 0 )
 | 
|            {
 | 
|              _iup_worker_interpolate( &V,
 | 
|                                       cur_touched + 1,
 | 
| @@ -7445,7 +6995,7 @@
 | 
|          }
 | 
|        }
 | 
|        contour++;
 | 
| -    } while ( contour < CUR.pts.n_contours );
 | 
| +    } while ( contour < exc->pts.n_contours );
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7456,7 +7006,8 @@
 | 
|    /* Stack:        uint32 (2 * uint32)... -->                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_DELTAP( INS_ARG )
 | 
| +  Ins_DELTAP( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
|      FT_ULong   nump, k;
 | 
|      FT_UShort  A;
 | 
| @@ -7466,52 +7017,52 @@
 | 
|      FT_UShort  B1, B2;
 | 
|  
 | 
|  
 | 
| -    if ( SUBPIXEL_HINTING                                        &&
 | 
| -         CUR.ignore_x_mode                                       &&
 | 
| -         CUR.iup_called                                          &&
 | 
| -         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
 | 
| +    if ( SUBPIXEL_HINTING                                         &&
 | 
| +         exc->ignore_x_mode                                       &&
 | 
| +         exc->iup_called                                          &&
 | 
| +         ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
 | 
|        goto Fail;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
|      /* Delta hinting is covered by US Patent 5159668. */
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
|        FT_Long  n = args[0] * 2;
 | 
|  
 | 
|  
 | 
| -      if ( CUR.args < n )
 | 
| +      if ( exc->args < n )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| -          CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| -        n = CUR.args;
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Too_Few_Arguments );
 | 
| +        n = exc->args;
 | 
|        }
 | 
|  
 | 
| -      CUR.args -= n;
 | 
| -      CUR.new_top = CUR.args;
 | 
| +      exc->args -= n;
 | 
| +      exc->new_top = exc->args;
 | 
|        return;
 | 
|      }
 | 
|  #endif
 | 
|  
 | 
| -    P = (FT_ULong)CUR_Func_cur_ppem();
 | 
| +    P    = (FT_ULong)exc->func_cur_ppem( exc );
 | 
|      nump = (FT_ULong)args[0];   /* some points theoretically may occur more
 | 
|                                     than once, thus UShort isn't enough */
 | 
|  
 | 
|      for ( k = 1; k <= nump; k++ )
 | 
|      {
 | 
| -      if ( CUR.args < 2 )
 | 
| +      if ( exc->args < 2 )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| -          CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| -        CUR.args = 0;
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Too_Few_Arguments );
 | 
| +        exc->args = 0;
 | 
|          goto Fail;
 | 
|        }
 | 
|  
 | 
| -      CUR.args -= 2;
 | 
| +      exc->args -= 2;
 | 
|  
 | 
| -      A = (FT_UShort)CUR.stack[CUR.args + 1];
 | 
| -      B = CUR.stack[CUR.args];
 | 
| +      A = (FT_UShort)exc->stack[exc->args + 1];
 | 
| +      B = exc->stack[exc->args];
 | 
|  
 | 
|        /* XXX: Because some popular fonts contain some invalid DeltaP */
 | 
|        /*      instructions, we simply ignore them when the stacked   */
 | 
| @@ -7519,11 +7070,11 @@
 | 
|        /*      error.  As a delta instruction doesn't change a glyph  */
 | 
|        /*      in great ways, this shouldn't be a problem.            */
 | 
|  
 | 
| -      if ( !BOUNDS( A, CUR.zp0.n_points ) )
 | 
| +      if ( !BOUNDS( A, exc->zp0.n_points ) )
 | 
|        {
 | 
|          C = ( (FT_ULong)B & 0xF0 ) >> 4;
 | 
|  
 | 
| -        switch ( CUR.opcode )
 | 
| +        switch ( exc->opcode )
 | 
|          {
 | 
|          case 0x5D:
 | 
|            break;
 | 
| @@ -7537,14 +7088,14 @@
 | 
|            break;
 | 
|          }
 | 
|  
 | 
| -        C += CUR.GS.delta_base;
 | 
| +        C += exc->GS.delta_base;
 | 
|  
 | 
|          if ( P == C )
 | 
|          {
 | 
|            B = ( (FT_ULong)B & 0xF ) - 8;
 | 
|            if ( B >= 0 )
 | 
|              B++;
 | 
| -          B *= 1L << ( 6 - CUR.GS.delta_shift );
 | 
| +          B *= 1L << ( 6 - exc->GS.delta_shift );
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|  
 | 
| @@ -7558,65 +7109,65 @@
 | 
|               *  - glyph is composite and freedom vector is not in subpixel
 | 
|               *    direction.
 | 
|               */
 | 
| -            if ( !CUR.ignore_x_mode                                   ||
 | 
| -                 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
 | 
| -                 ( CUR.is_composite && CUR.GS.freeVector.y != 0 )     )
 | 
| -              CUR_Func_move( &CUR.zp0, A, B );
 | 
| +            if ( !exc->ignore_x_mode                                   ||
 | 
| +                 ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
 | 
| +                 ( exc->is_composite && exc->GS.freeVector.y != 0 )    )
 | 
| +              exc->func_move( exc, &exc->zp0, A, B );
 | 
|  
 | 
|              /* Otherwise, apply subpixel hinting and compatibility mode */
 | 
|              /* rules, always skipping deltas in subpixel direction.     */
 | 
| -            else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
 | 
| +            else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
 | 
|              {
 | 
|                /* save the y value of the point now; compare after move */
 | 
| -              B1 = (FT_UShort)CUR.zp0.cur[A].y;
 | 
| +              B1 = (FT_UShort)exc->zp0.cur[A].y;
 | 
|  
 | 
|                /* Standard subpixel hinting: Allow y move for y-touched */
 | 
|                /* points.  This messes up DejaVu ...                    */
 | 
| -              if ( !CUR.face->sph_compatibility_mode          &&
 | 
| -                   ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
 | 
| -                CUR_Func_move( &CUR.zp0, A, B );
 | 
| +              if ( !exc->face->sph_compatibility_mode          &&
 | 
| +                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
 | 
| +                exc->func_move( exc, &exc->zp0, A, B );
 | 
|  
 | 
|                /* compatibility mode */
 | 
| -              else if ( CUR.face->sph_compatibility_mode                      &&
 | 
| -                        !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
 | 
| +              else if ( exc->face->sph_compatibility_mode                        &&
 | 
| +                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
 | 
|                {
 | 
| -                if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
 | 
| +                if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
 | 
|                    B = FT_PIX_ROUND( B1 + B ) - B1;
 | 
|  
 | 
|                  /* Allow delta move if using sph_compatibility_mode,   */
 | 
|                  /* IUP has not been called, and point is touched on Y. */
 | 
| -                if ( !CUR.iup_called                            &&
 | 
| -                     ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
 | 
| -                  CUR_Func_move( &CUR.zp0, A, B );
 | 
| +                if ( !exc->iup_called                            &&
 | 
| +                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
 | 
| +                  exc->func_move( exc, &exc->zp0, A, B );
 | 
|                }
 | 
|  
 | 
| -              B2 = (FT_UShort)CUR.zp0.cur[A].y;
 | 
| +              B2 = (FT_UShort)exc->zp0.cur[A].y;
 | 
|  
 | 
|                /* Reverse this move if it results in a disallowed move */
 | 
| -              if ( CUR.GS.freeVector.y != 0                           &&
 | 
| -                   ( ( CUR.face->sph_compatibility_mode           &&
 | 
| +              if ( exc->GS.freeVector.y != 0                          &&
 | 
| +                   ( ( exc->face->sph_compatibility_mode          &&
 | 
|                         ( B1 & 63 ) == 0                           &&
 | 
|                         ( B2 & 63 ) != 0                           ) ||
 | 
| -                     ( ( CUR.sph_tweak_flags                    &
 | 
| +                     ( ( exc->sph_tweak_flags                   &
 | 
|                           SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
 | 
|                         ( B1 & 63 ) != 0                           &&
 | 
|                         ( B2 & 63 ) != 0                           ) ) )
 | 
| -                CUR_Func_move( &CUR.zp0, A, -B );
 | 
| +                exc->func_move( exc, &exc->zp0, A, -B );
 | 
|              }
 | 
|            }
 | 
|            else
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -            CUR_Func_move( &CUR.zp0, A, B );
 | 
| +            exc->func_move( exc, &exc->zp0, A, B );
 | 
|          }
 | 
|        }
 | 
|        else
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7627,7 +7178,8 @@
 | 
|    /* Stack:        uint32 (2 * uint32)... -->                              */
 | 
|    /*                                                                       */
 | 
|    static void
 | 
| -  Ins_DELTAC( INS_ARG )
 | 
| +  Ins_DELTAC( TT_ExecContext  exc,
 | 
| +              FT_Long*        args )
 | 
|    {
 | 
|      FT_ULong  nump, k;
 | 
|      FT_ULong  A, C, P;
 | 
| @@ -7636,47 +7188,47 @@
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
 | 
|      /* Delta hinting is covered by US Patent 5159668. */
 | 
| -    if ( CUR.face->unpatented_hinting )
 | 
| +    if ( exc->face->unpatented_hinting )
 | 
|      {
 | 
|        FT_Long  n = args[0] * 2;
 | 
|  
 | 
|  
 | 
| -      if ( CUR.args < n )
 | 
| +      if ( exc->args < n )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| -          CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| -        n = CUR.args;
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Too_Few_Arguments );
 | 
| +        n = exc->args;
 | 
|        }
 | 
|  
 | 
| -      CUR.args -= n;
 | 
| -      CUR.new_top = CUR.args;
 | 
| +      exc->args -= n;
 | 
| +      exc->new_top = exc->args;
 | 
|        return;
 | 
|      }
 | 
|  #endif
 | 
|  
 | 
| -    P = (FT_ULong)CUR_Func_cur_ppem();
 | 
| +    P    = (FT_ULong)exc->func_cur_ppem( exc );
 | 
|      nump = (FT_ULong)args[0];
 | 
|  
 | 
|      for ( k = 1; k <= nump; k++ )
 | 
|      {
 | 
| -      if ( CUR.args < 2 )
 | 
| +      if ( exc->args < 2 )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| -          CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| -        CUR.args = 0;
 | 
| +        if ( exc->pedantic_hinting )
 | 
| +          exc->error = FT_THROW( Too_Few_Arguments );
 | 
| +        exc->args = 0;
 | 
|          goto Fail;
 | 
|        }
 | 
|  
 | 
| -      CUR.args -= 2;
 | 
| +      exc->args -= 2;
 | 
|  
 | 
| -      A = (FT_ULong)CUR.stack[CUR.args + 1];
 | 
| -      B = CUR.stack[CUR.args];
 | 
| +      A = (FT_ULong)exc->stack[exc->args + 1];
 | 
| +      B = exc->stack[exc->args];
 | 
|  
 | 
| -      if ( BOUNDSL( A, CUR.cvtSize ) )
 | 
| +      if ( BOUNDSL( A, exc->cvtSize ) )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          exc->error = FT_THROW( Invalid_Reference );
 | 
|            return;
 | 
|          }
 | 
|        }
 | 
| @@ -7684,7 +7236,7 @@
 | 
|        {
 | 
|          C = ( (FT_ULong)B & 0xF0 ) >> 4;
 | 
|  
 | 
| -        switch ( CUR.opcode )
 | 
| +        switch ( exc->opcode )
 | 
|          {
 | 
|          case 0x73:
 | 
|            break;
 | 
| @@ -7698,22 +7250,22 @@
 | 
|            break;
 | 
|          }
 | 
|  
 | 
| -        C += CUR.GS.delta_base;
 | 
| +        C += exc->GS.delta_base;
 | 
|  
 | 
|          if ( P == C )
 | 
|          {
 | 
|            B = ( (FT_ULong)B & 0xF ) - 8;
 | 
|            if ( B >= 0 )
 | 
|              B++;
 | 
| -          B *= 1L << ( 6 - CUR.GS.delta_shift );
 | 
| +          B *= 1L << ( 6 - exc->GS.delta_shift );
 | 
|  
 | 
| -          CUR_Func_move_cvt( A, B );
 | 
| +          exc->func_move_cvt( exc, A, B );
 | 
|          }
 | 
|        }
 | 
|      }
 | 
|  
 | 
|    Fail:
 | 
| -    CUR.new_top = CUR.args;
 | 
| +    exc->new_top = exc->args;
 | 
|    }
 | 
|  
 | 
|  
 | 
| @@ -7730,8 +7282,17 @@
 | 
|    /* Opcode range: 0x88                                                    */
 | 
|    /* Stack:        uint32 --> uint32                                       */
 | 
|    /*                                                                       */
 | 
| +  /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May     */
 | 
| +  /*      2015) not documented in the OpenType specification.              */
 | 
| +  /*                                                                       */
 | 
| +  /*      Selector bit 11 is incorrectly described as bit 8, while the     */
 | 
| +  /*      real meaning of bit 8 (vertical LCD subpixels) stays             */
 | 
| +  /*      undocumented.  The same mistake can be found in Greg Hitchcock's */
 | 
| +  /*      whitepaper.                                                      */
 | 
| +  /*                                                                       */
 | 
|    static void
 | 
| -  Ins_GETINFO( INS_ARG )
 | 
| +  Ins_GETINFO( TT_ExecContext  exc,
 | 
| +               FT_Long*        args )
 | 
|    {
 | 
|      FT_Long  K;
 | 
|  
 | 
| @@ -7744,13 +7305,20 @@
 | 
|      /* Selector Bit:  0             */
 | 
|      /* Return Bit(s): 0-7           */
 | 
|      /*                              */
 | 
| -    if ( SUBPIXEL_HINTING     &&
 | 
| -         ( args[0] & 1 ) != 0 &&
 | 
| -         CUR.ignore_x_mode    )
 | 
| +    if ( SUBPIXEL_HINTING      &&
 | 
| +         ( args[0] & 1 ) != 0  &&
 | 
| +         exc->subpixel_hinting )
 | 
|      {
 | 
| -      K = CUR.rasterizer_version;
 | 
| -      FT_TRACE7(( "Setting rasterizer version %d\n",
 | 
| -                  CUR.rasterizer_version ));
 | 
| +      if ( exc->ignore_x_mode )
 | 
| +      {
 | 
| +        /* if in ClearType backwards compatibility mode,        */
 | 
| +        /* we sometimes change the TrueType version dynamically */
 | 
| +        K = exc->rasterizer_version;
 | 
| +        FT_TRACE6(( "Setting rasterizer version %d\n",
 | 
| +                    exc->rasterizer_version ));
 | 
| +      }
 | 
| +      else
 | 
| +        K = TT_INTERPRETER_VERSION_38;
 | 
|      }
 | 
|      else
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
| @@ -7762,7 +7330,7 @@
 | 
|      /* Selector Bit:  1             */
 | 
|      /* Return Bit(s): 8             */
 | 
|      /*                              */
 | 
| -    if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
 | 
| +    if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
 | 
|        K |= 0x80;
 | 
|  
 | 
|      /********************************/
 | 
| @@ -7770,7 +7338,7 @@
 | 
|      /* Selector Bit:  2             */
 | 
|      /* Return Bit(s): 9             */
 | 
|      /*                              */
 | 
| -    if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
 | 
| +    if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
 | 
|        K |= 1 << 8;
 | 
|  
 | 
|      /********************************/
 | 
| @@ -7778,24 +7346,23 @@
 | 
|      /* Selector Bit:  5             */
 | 
|      /* Return Bit(s): 12            */
 | 
|      /*                              */
 | 
| -    if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
 | 
| +    if ( ( args[0] & 32 ) != 0 && exc->grayscale )
 | 
|        K |= 1 << 12;
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|  
 | 
| -    if ( SUBPIXEL_HINTING                                    &&
 | 
| -         CUR.ignore_x_mode                                   &&
 | 
| -         CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
 | 
| +    if ( SUBPIXEL_HINTING                                     &&
 | 
| +         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
 | 
|      {
 | 
|  
 | 
| -      if ( CUR.rasterizer_version >= 37 )
 | 
| +      if ( exc->rasterizer_version >= 37 )
 | 
|        {
 | 
|          /********************************/
 | 
|          /* HINTING FOR SUBPIXEL         */
 | 
|          /* Selector Bit:  6             */
 | 
|          /* Return Bit(s): 13            */
 | 
|          /*                              */
 | 
| -        if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
 | 
| +        if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
 | 
|            K |= 1 << 13;
 | 
|  
 | 
|          /********************************/
 | 
| @@ -7804,16 +7371,16 @@
 | 
|          /* Return Bit(s): 14            */
 | 
|          /*                              */
 | 
|          /* Functionality still needs to be added */
 | 
| -        if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
 | 
| +        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
 | 
|            K |= 1 << 14;
 | 
|  
 | 
|          /********************************/
 | 
| -        /* SYMMETRICAL SMOOTHING        */
 | 
| +        /* VERTICAL LCD SUBPIXELS?      */
 | 
|          /* Selector Bit:  8             */
 | 
|          /* Return Bit(s): 15            */
 | 
|          /*                              */
 | 
|          /* Functionality still needs to be added */
 | 
| -        if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
 | 
| +        if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
 | 
|            K |= 1 << 15;
 | 
|  
 | 
|          /********************************/
 | 
| @@ -7822,10 +7389,10 @@
 | 
|          /* Return Bit(s): 16            */
 | 
|          /*                              */
 | 
|          /* Functionality still needs to be added */
 | 
| -        if ( ( args[0] & 512 ) != 0 && CUR.bgr )
 | 
| +        if ( ( args[0] & 512 ) != 0 && exc->bgr )
 | 
|            K |= 1 << 16;
 | 
|  
 | 
| -        if ( CUR.rasterizer_version >= 38 )
 | 
| +        if ( exc->rasterizer_version >= 38 )
 | 
|          {
 | 
|            /********************************/
 | 
|            /* SUBPIXEL POSITIONED?         */
 | 
| @@ -7833,8 +7400,26 @@
 | 
|            /* Return Bit(s): 17            */
 | 
|            /*                              */
 | 
|            /* Functionality still needs to be added */
 | 
| -          if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
 | 
| +          if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
 | 
|              K |= 1 << 17;
 | 
| +
 | 
| +          /********************************/
 | 
| +          /* SYMMETRICAL SMOOTHING        */
 | 
| +          /* Selector Bit:  11            */
 | 
| +          /* Return Bit(s): 18            */
 | 
| +          /*                              */
 | 
| +          /* Functionality still needs to be added */
 | 
| +          if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
 | 
| +            K |= 1 << 18;
 | 
| +
 | 
| +          /********************************/
 | 
| +          /* GRAY CLEARTYPE               */
 | 
| +          /* Selector Bit:  12            */
 | 
| +          /* Return Bit(s): 19            */
 | 
| +          /*                              */
 | 
| +          /* Functionality still needs to be added */
 | 
| +          if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
 | 
| +            K |= 1 << 19;
 | 
|          }
 | 
|        }
 | 
|      }
 | 
| @@ -7846,331 +7431,43 @@
 | 
|  
 | 
|  
 | 
|    static void
 | 
| -  Ins_UNKNOWN( INS_ARG )
 | 
| +  Ins_UNKNOWN( TT_ExecContext  exc )
 | 
|    {
 | 
| -    TT_DefRecord*  def   = CUR.IDefs;
 | 
| -    TT_DefRecord*  limit = def + CUR.numIDefs;
 | 
| -
 | 
| -    FT_UNUSED_ARG;
 | 
| +    TT_DefRecord*  def   = exc->IDefs;
 | 
| +    TT_DefRecord*  limit = def + exc->numIDefs;
 | 
|  
 | 
|  
 | 
|      for ( ; def < limit; def++ )
 | 
|      {
 | 
| -      if ( (FT_Byte)def->opc == CUR.opcode && def->active )
 | 
| +      if ( (FT_Byte)def->opc == exc->opcode && def->active )
 | 
|        {
 | 
|          TT_CallRec*  call;
 | 
|  
 | 
|  
 | 
| -        if ( CUR.callTop >= CUR.callSize )
 | 
| +        if ( exc->callTop >= exc->callSize )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Stack_Overflow );
 | 
| +          exc->error = FT_THROW( Stack_Overflow );
 | 
|            return;
 | 
|          }
 | 
|  
 | 
| -        call = CUR.callStack + CUR.callTop++;
 | 
| +        call = exc->callStack + exc->callTop++;
 | 
|  
 | 
| -        call->Caller_Range = CUR.curRange;
 | 
| -        call->Caller_IP    = CUR.IP + 1;
 | 
| +        call->Caller_Range = exc->curRange;
 | 
| +        call->Caller_IP    = exc->IP + 1;
 | 
|          call->Cur_Count    = 1;
 | 
|          call->Def          = def;
 | 
|  
 | 
| -        INS_Goto_CodeRange( def->range, def->start );
 | 
| +        Ins_Goto_CodeRange( exc, def->range, def->start );
 | 
|  
 | 
| -        CUR.step_ins = FALSE;
 | 
| +        exc->step_ins = FALSE;
 | 
|          return;
 | 
|        }
 | 
|      }
 | 
|  
 | 
| -    CUR.error = FT_THROW( Invalid_Opcode );
 | 
| +    exc->error = FT_THROW( Invalid_Opcode );
 | 
|    }
 | 
|  
 | 
|  
 | 
| -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
 | 
| -
 | 
| -
 | 
| -  static
 | 
| -  TInstruction_Function  Instruct_Dispatch[256] =
 | 
| -  {
 | 
| -    /* Opcodes are gathered in groups of 16. */
 | 
| -    /* Please keep the spaces as they are.   */
 | 
| -
 | 
| -    /*  SVTCA  y  */  Ins_SVTCA,
 | 
| -    /*  SVTCA  x  */  Ins_SVTCA,
 | 
| -    /*  SPvTCA y  */  Ins_SPVTCA,
 | 
| -    /*  SPvTCA x  */  Ins_SPVTCA,
 | 
| -    /*  SFvTCA y  */  Ins_SFVTCA,
 | 
| -    /*  SFvTCA x  */  Ins_SFVTCA,
 | 
| -    /*  SPvTL //  */  Ins_SPVTL,
 | 
| -    /*  SPvTL +   */  Ins_SPVTL,
 | 
| -    /*  SFvTL //  */  Ins_SFVTL,
 | 
| -    /*  SFvTL +   */  Ins_SFVTL,
 | 
| -    /*  SPvFS     */  Ins_SPVFS,
 | 
| -    /*  SFvFS     */  Ins_SFVFS,
 | 
| -    /*  GPV       */  Ins_GPV,
 | 
| -    /*  GFV       */  Ins_GFV,
 | 
| -    /*  SFvTPv    */  Ins_SFVTPV,
 | 
| -    /*  ISECT     */  Ins_ISECT,
 | 
| -
 | 
| -    /*  SRP0      */  Ins_SRP0,
 | 
| -    /*  SRP1      */  Ins_SRP1,
 | 
| -    /*  SRP2      */  Ins_SRP2,
 | 
| -    /*  SZP0      */  Ins_SZP0,
 | 
| -    /*  SZP1      */  Ins_SZP1,
 | 
| -    /*  SZP2      */  Ins_SZP2,
 | 
| -    /*  SZPS      */  Ins_SZPS,
 | 
| -    /*  SLOOP     */  Ins_SLOOP,
 | 
| -    /*  RTG       */  Ins_RTG,
 | 
| -    /*  RTHG      */  Ins_RTHG,
 | 
| -    /*  SMD       */  Ins_SMD,
 | 
| -    /*  ELSE      */  Ins_ELSE,
 | 
| -    /*  JMPR      */  Ins_JMPR,
 | 
| -    /*  SCvTCi    */  Ins_SCVTCI,
 | 
| -    /*  SSwCi     */  Ins_SSWCI,
 | 
| -    /*  SSW       */  Ins_SSW,
 | 
| -
 | 
| -    /*  DUP       */  Ins_DUP,
 | 
| -    /*  POP       */  Ins_POP,
 | 
| -    /*  CLEAR     */  Ins_CLEAR,
 | 
| -    /*  SWAP      */  Ins_SWAP,
 | 
| -    /*  DEPTH     */  Ins_DEPTH,
 | 
| -    /*  CINDEX    */  Ins_CINDEX,
 | 
| -    /*  MINDEX    */  Ins_MINDEX,
 | 
| -    /*  AlignPTS  */  Ins_ALIGNPTS,
 | 
| -    /*  INS_0x28  */  Ins_UNKNOWN,
 | 
| -    /*  UTP       */  Ins_UTP,
 | 
| -    /*  LOOPCALL  */  Ins_LOOPCALL,
 | 
| -    /*  CALL      */  Ins_CALL,
 | 
| -    /*  FDEF      */  Ins_FDEF,
 | 
| -    /*  ENDF      */  Ins_ENDF,
 | 
| -    /*  MDAP[0]   */  Ins_MDAP,
 | 
| -    /*  MDAP[1]   */  Ins_MDAP,
 | 
| -
 | 
| -    /*  IUP[0]    */  Ins_IUP,
 | 
| -    /*  IUP[1]    */  Ins_IUP,
 | 
| -    /*  SHP[0]    */  Ins_SHP,
 | 
| -    /*  SHP[1]    */  Ins_SHP,
 | 
| -    /*  SHC[0]    */  Ins_SHC,
 | 
| -    /*  SHC[1]    */  Ins_SHC,
 | 
| -    /*  SHZ[0]    */  Ins_SHZ,
 | 
| -    /*  SHZ[1]    */  Ins_SHZ,
 | 
| -    /*  SHPIX     */  Ins_SHPIX,
 | 
| -    /*  IP        */  Ins_IP,
 | 
| -    /*  MSIRP[0]  */  Ins_MSIRP,
 | 
| -    /*  MSIRP[1]  */  Ins_MSIRP,
 | 
| -    /*  AlignRP   */  Ins_ALIGNRP,
 | 
| -    /*  RTDG      */  Ins_RTDG,
 | 
| -    /*  MIAP[0]   */  Ins_MIAP,
 | 
| -    /*  MIAP[1]   */  Ins_MIAP,
 | 
| -
 | 
| -    /*  NPushB    */  Ins_NPUSHB,
 | 
| -    /*  NPushW    */  Ins_NPUSHW,
 | 
| -    /*  WS        */  Ins_WS,
 | 
| -    /*  RS        */  Ins_RS,
 | 
| -    /*  WCvtP     */  Ins_WCVTP,
 | 
| -    /*  RCvt      */  Ins_RCVT,
 | 
| -    /*  GC[0]     */  Ins_GC,
 | 
| -    /*  GC[1]     */  Ins_GC,
 | 
| -    /*  SCFS      */  Ins_SCFS,
 | 
| -    /*  MD[0]     */  Ins_MD,
 | 
| -    /*  MD[1]     */  Ins_MD,
 | 
| -    /*  MPPEM     */  Ins_MPPEM,
 | 
| -    /*  MPS       */  Ins_MPS,
 | 
| -    /*  FlipON    */  Ins_FLIPON,
 | 
| -    /*  FlipOFF   */  Ins_FLIPOFF,
 | 
| -    /*  DEBUG     */  Ins_DEBUG,
 | 
| -
 | 
| -    /*  LT        */  Ins_LT,
 | 
| -    /*  LTEQ      */  Ins_LTEQ,
 | 
| -    /*  GT        */  Ins_GT,
 | 
| -    /*  GTEQ      */  Ins_GTEQ,
 | 
| -    /*  EQ        */  Ins_EQ,
 | 
| -    /*  NEQ       */  Ins_NEQ,
 | 
| -    /*  ODD       */  Ins_ODD,
 | 
| -    /*  EVEN      */  Ins_EVEN,
 | 
| -    /*  IF        */  Ins_IF,
 | 
| -    /*  EIF       */  Ins_EIF,
 | 
| -    /*  AND       */  Ins_AND,
 | 
| -    /*  OR        */  Ins_OR,
 | 
| -    /*  NOT       */  Ins_NOT,
 | 
| -    /*  DeltaP1   */  Ins_DELTAP,
 | 
| -    /*  SDB       */  Ins_SDB,
 | 
| -    /*  SDS       */  Ins_SDS,
 | 
| -
 | 
| -    /*  ADD       */  Ins_ADD,
 | 
| -    /*  SUB       */  Ins_SUB,
 | 
| -    /*  DIV       */  Ins_DIV,
 | 
| -    /*  MUL       */  Ins_MUL,
 | 
| -    /*  ABS       */  Ins_ABS,
 | 
| -    /*  NEG       */  Ins_NEG,
 | 
| -    /*  FLOOR     */  Ins_FLOOR,
 | 
| -    /*  CEILING   */  Ins_CEILING,
 | 
| -    /*  ROUND[0]  */  Ins_ROUND,
 | 
| -    /*  ROUND[1]  */  Ins_ROUND,
 | 
| -    /*  ROUND[2]  */  Ins_ROUND,
 | 
| -    /*  ROUND[3]  */  Ins_ROUND,
 | 
| -    /*  NROUND[0] */  Ins_NROUND,
 | 
| -    /*  NROUND[1] */  Ins_NROUND,
 | 
| -    /*  NROUND[2] */  Ins_NROUND,
 | 
| -    /*  NROUND[3] */  Ins_NROUND,
 | 
| -
 | 
| -    /*  WCvtF     */  Ins_WCVTF,
 | 
| -    /*  DeltaP2   */  Ins_DELTAP,
 | 
| -    /*  DeltaP3   */  Ins_DELTAP,
 | 
| -    /*  DeltaCn[0] */ Ins_DELTAC,
 | 
| -    /*  DeltaCn[1] */ Ins_DELTAC,
 | 
| -    /*  DeltaCn[2] */ Ins_DELTAC,
 | 
| -    /*  SROUND    */  Ins_SROUND,
 | 
| -    /*  S45Round  */  Ins_S45ROUND,
 | 
| -    /*  JROT      */  Ins_JROT,
 | 
| -    /*  JROF      */  Ins_JROF,
 | 
| -    /*  ROFF      */  Ins_ROFF,
 | 
| -    /*  INS_0x7B  */  Ins_UNKNOWN,
 | 
| -    /*  RUTG      */  Ins_RUTG,
 | 
| -    /*  RDTG      */  Ins_RDTG,
 | 
| -    /*  SANGW     */  Ins_SANGW,
 | 
| -    /*  AA        */  Ins_AA,
 | 
| -
 | 
| -    /*  FlipPT    */  Ins_FLIPPT,
 | 
| -    /*  FlipRgON  */  Ins_FLIPRGON,
 | 
| -    /*  FlipRgOFF */  Ins_FLIPRGOFF,
 | 
| -    /*  INS_0x83  */  Ins_UNKNOWN,
 | 
| -    /*  INS_0x84  */  Ins_UNKNOWN,
 | 
| -    /*  ScanCTRL  */  Ins_SCANCTRL,
 | 
| -    /*  SDPVTL[0] */  Ins_SDPVTL,
 | 
| -    /*  SDPVTL[1] */  Ins_SDPVTL,
 | 
| -    /*  GetINFO   */  Ins_GETINFO,
 | 
| -    /*  IDEF      */  Ins_IDEF,
 | 
| -    /*  ROLL      */  Ins_ROLL,
 | 
| -    /*  MAX       */  Ins_MAX,
 | 
| -    /*  MIN       */  Ins_MIN,
 | 
| -    /*  ScanTYPE  */  Ins_SCANTYPE,
 | 
| -    /*  InstCTRL  */  Ins_INSTCTRL,
 | 
| -    /*  INS_0x8F  */  Ins_UNKNOWN,
 | 
| -
 | 
| -    /*  INS_0x90  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x91  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x92  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x93  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x94  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x95  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x96  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x97  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x98  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x99  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9A  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9B  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9C  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9D  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9E  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0x9F  */   Ins_UNKNOWN,
 | 
| -
 | 
| -    /*  INS_0xA0  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA1  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA2  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA3  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA4  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA5  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA6  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA7  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA8  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xA9  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAA  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAB  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAC  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAD  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAE  */   Ins_UNKNOWN,
 | 
| -    /*  INS_0xAF  */   Ins_UNKNOWN,
 | 
| -
 | 
| -    /*  PushB[0]  */  Ins_PUSHB,
 | 
| -    /*  PushB[1]  */  Ins_PUSHB,
 | 
| -    /*  PushB[2]  */  Ins_PUSHB,
 | 
| -    /*  PushB[3]  */  Ins_PUSHB,
 | 
| -    /*  PushB[4]  */  Ins_PUSHB,
 | 
| -    /*  PushB[5]  */  Ins_PUSHB,
 | 
| -    /*  PushB[6]  */  Ins_PUSHB,
 | 
| -    /*  PushB[7]  */  Ins_PUSHB,
 | 
| -    /*  PushW[0]  */  Ins_PUSHW,
 | 
| -    /*  PushW[1]  */  Ins_PUSHW,
 | 
| -    /*  PushW[2]  */  Ins_PUSHW,
 | 
| -    /*  PushW[3]  */  Ins_PUSHW,
 | 
| -    /*  PushW[4]  */  Ins_PUSHW,
 | 
| -    /*  PushW[5]  */  Ins_PUSHW,
 | 
| -    /*  PushW[6]  */  Ins_PUSHW,
 | 
| -    /*  PushW[7]  */  Ins_PUSHW,
 | 
| -
 | 
| -    /*  MDRP[00]  */  Ins_MDRP,
 | 
| -    /*  MDRP[01]  */  Ins_MDRP,
 | 
| -    /*  MDRP[02]  */  Ins_MDRP,
 | 
| -    /*  MDRP[03]  */  Ins_MDRP,
 | 
| -    /*  MDRP[04]  */  Ins_MDRP,
 | 
| -    /*  MDRP[05]  */  Ins_MDRP,
 | 
| -    /*  MDRP[06]  */  Ins_MDRP,
 | 
| -    /*  MDRP[07]  */  Ins_MDRP,
 | 
| -    /*  MDRP[08]  */  Ins_MDRP,
 | 
| -    /*  MDRP[09]  */  Ins_MDRP,
 | 
| -    /*  MDRP[10]  */  Ins_MDRP,
 | 
| -    /*  MDRP[11]  */  Ins_MDRP,
 | 
| -    /*  MDRP[12]  */  Ins_MDRP,
 | 
| -    /*  MDRP[13]  */  Ins_MDRP,
 | 
| -    /*  MDRP[14]  */  Ins_MDRP,
 | 
| -    /*  MDRP[15]  */  Ins_MDRP,
 | 
| -
 | 
| -    /*  MDRP[16]  */  Ins_MDRP,
 | 
| -    /*  MDRP[17]  */  Ins_MDRP,
 | 
| -    /*  MDRP[18]  */  Ins_MDRP,
 | 
| -    /*  MDRP[19]  */  Ins_MDRP,
 | 
| -    /*  MDRP[20]  */  Ins_MDRP,
 | 
| -    /*  MDRP[21]  */  Ins_MDRP,
 | 
| -    /*  MDRP[22]  */  Ins_MDRP,
 | 
| -    /*  MDRP[23]  */  Ins_MDRP,
 | 
| -    /*  MDRP[24]  */  Ins_MDRP,
 | 
| -    /*  MDRP[25]  */  Ins_MDRP,
 | 
| -    /*  MDRP[26]  */  Ins_MDRP,
 | 
| -    /*  MDRP[27]  */  Ins_MDRP,
 | 
| -    /*  MDRP[28]  */  Ins_MDRP,
 | 
| -    /*  MDRP[29]  */  Ins_MDRP,
 | 
| -    /*  MDRP[30]  */  Ins_MDRP,
 | 
| -    /*  MDRP[31]  */  Ins_MDRP,
 | 
| -
 | 
| -    /*  MIRP[00]  */  Ins_MIRP,
 | 
| -    /*  MIRP[01]  */  Ins_MIRP,
 | 
| -    /*  MIRP[02]  */  Ins_MIRP,
 | 
| -    /*  MIRP[03]  */  Ins_MIRP,
 | 
| -    /*  MIRP[04]  */  Ins_MIRP,
 | 
| -    /*  MIRP[05]  */  Ins_MIRP,
 | 
| -    /*  MIRP[06]  */  Ins_MIRP,
 | 
| -    /*  MIRP[07]  */  Ins_MIRP,
 | 
| -    /*  MIRP[08]  */  Ins_MIRP,
 | 
| -    /*  MIRP[09]  */  Ins_MIRP,
 | 
| -    /*  MIRP[10]  */  Ins_MIRP,
 | 
| -    /*  MIRP[11]  */  Ins_MIRP,
 | 
| -    /*  MIRP[12]  */  Ins_MIRP,
 | 
| -    /*  MIRP[13]  */  Ins_MIRP,
 | 
| -    /*  MIRP[14]  */  Ins_MIRP,
 | 
| -    /*  MIRP[15]  */  Ins_MIRP,
 | 
| -
 | 
| -    /*  MIRP[16]  */  Ins_MIRP,
 | 
| -    /*  MIRP[17]  */  Ins_MIRP,
 | 
| -    /*  MIRP[18]  */  Ins_MIRP,
 | 
| -    /*  MIRP[19]  */  Ins_MIRP,
 | 
| -    /*  MIRP[20]  */  Ins_MIRP,
 | 
| -    /*  MIRP[21]  */  Ins_MIRP,
 | 
| -    /*  MIRP[22]  */  Ins_MIRP,
 | 
| -    /*  MIRP[23]  */  Ins_MIRP,
 | 
| -    /*  MIRP[24]  */  Ins_MIRP,
 | 
| -    /*  MIRP[25]  */  Ins_MIRP,
 | 
| -    /*  MIRP[26]  */  Ins_MIRP,
 | 
| -    /*  MIRP[27]  */  Ins_MIRP,
 | 
| -    /*  MIRP[28]  */  Ins_MIRP,
 | 
| -    /*  MIRP[29]  */  Ins_MIRP,
 | 
| -    /*  MIRP[30]  */  Ins_MIRP,
 | 
| -    /*  MIRP[31]  */  Ins_MIRP
 | 
| -  };
 | 
| -
 | 
| -
 | 
| -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
 | 
| -
 | 
| -
 | 
|    /*************************************************************************/
 | 
|    /*                                                                       */
 | 
|    /* RUN                                                                   */
 | 
| @@ -8198,8 +7495,6 @@
 | 
|    /*                                                                       */
 | 
|    /* THIS IS THE INTERPRETER'S MAIN LOOP.                                  */
 | 
|    /*                                                                       */
 | 
| -  /*  Instructions appear in the specification's order.                    */
 | 
| -  /*                                                                       */
 | 
|    /*************************************************************************/
 | 
|  
 | 
|  
 | 
| @@ -8225,90 +7520,100 @@
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
 | 
| -    if ( !exc )
 | 
| -      return FT_THROW( Invalid_Argument );
 | 
| -
 | 
| -    cur = *exc;
 | 
| -#endif
 | 
| -
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
| -    CUR.iup_called = FALSE;
 | 
| +    exc->iup_called = FALSE;
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
|      /* set PPEM and CVT functions */
 | 
| -    CUR.tt_metrics.ratio = 0;
 | 
| -    if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
 | 
| +    exc->tt_metrics.ratio = 0;
 | 
| +    if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
 | 
|      {
 | 
|        /* non-square pixels, use the stretched routines */
 | 
| -      CUR.func_cur_ppem  = Current_Ppem_Stretched;
 | 
| -      CUR.func_read_cvt  = Read_CVT_Stretched;
 | 
| -      CUR.func_write_cvt = Write_CVT_Stretched;
 | 
| -      CUR.func_move_cvt  = Move_CVT_Stretched;
 | 
| +      exc->func_cur_ppem  = Current_Ppem_Stretched;
 | 
| +      exc->func_read_cvt  = Read_CVT_Stretched;
 | 
| +      exc->func_write_cvt = Write_CVT_Stretched;
 | 
| +      exc->func_move_cvt  = Move_CVT_Stretched;
 | 
|      }
 | 
|      else
 | 
|      {
 | 
|        /* square pixels, use normal routines */
 | 
| -      CUR.func_cur_ppem  = Current_Ppem;
 | 
| -      CUR.func_read_cvt  = Read_CVT;
 | 
| -      CUR.func_write_cvt = Write_CVT;
 | 
| -      CUR.func_move_cvt  = Move_CVT;
 | 
| +      exc->func_cur_ppem  = Current_Ppem;
 | 
| +      exc->func_read_cvt  = Read_CVT;
 | 
| +      exc->func_write_cvt = Write_CVT;
 | 
| +      exc->func_move_cvt  = Move_CVT;
 | 
|      }
 | 
|  
 | 
| -    COMPUTE_Funcs();
 | 
| -    COMPUTE_Round( (FT_Byte)exc->GS.round_state );
 | 
| +    Compute_Funcs( exc );
 | 
| +    Compute_Round( exc, (FT_Byte)exc->GS.round_state );
 | 
|  
 | 
|      do
 | 
|      {
 | 
| -      CUR.opcode = CUR.code[CUR.IP];
 | 
| +      exc->opcode = exc->code[exc->IP];
 | 
|  
 | 
| -      FT_TRACE7(( "  " ));
 | 
| -      FT_TRACE7(( opcode_name[CUR.opcode] ));
 | 
| -      FT_TRACE7(( "\n" ));
 | 
| +#ifdef FT_DEBUG_LEVEL_TRACE
 | 
| +      {
 | 
| +        FT_Long  cnt = FT_MIN( 8, exc->top );
 | 
| +        FT_Long  n;
 | 
| +
 | 
| +
 | 
| +        /* if tracing level is 7, show current code position */
 | 
| +        /* and the first few stack elements also             */
 | 
| +        FT_TRACE6(( "  " ));
 | 
| +        FT_TRACE7(( "%06d ", exc->IP ));
 | 
| +        FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
 | 
| +        FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
 | 
| +                              ? 2
 | 
| +                              : 12 - ( *opcode_name[exc->opcode] - '0' ),
 | 
| +                              "#" ));
 | 
| +        for ( n = 0; n < cnt; n++ )
 | 
| +          FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
 | 
| +        FT_TRACE6(( "\n" ));
 | 
| +      }
 | 
| +#endif /* FT_DEBUG_LEVEL_TRACE */
 | 
|  
 | 
| -      if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
 | 
| +      if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
 | 
|        {
 | 
| -        if ( CUR.IP + 1 >= CUR.codeSize )
 | 
| +        if ( exc->IP + 1 >= exc->codeSize )
 | 
|            goto LErrorCodeOverflow_;
 | 
|  
 | 
| -        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
 | 
| +        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
 | 
|        }
 | 
|  
 | 
| -      if ( CUR.IP + CUR.length > CUR.codeSize )
 | 
| +      if ( exc->IP + exc->length > exc->codeSize )
 | 
|          goto LErrorCodeOverflow_;
 | 
|  
 | 
|        /* First, let's check for empty stack and overflow */
 | 
| -      CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
 | 
| +      exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
 | 
|  
 | 
|        /* `args' is the top of the stack once arguments have been popped. */
 | 
|        /* One can also interpret it as the index of the last argument.    */
 | 
| -      if ( CUR.args < 0 )
 | 
| +      if ( exc->args < 0 )
 | 
|        {
 | 
| -        if ( CUR.pedantic_hinting )
 | 
| +        if ( exc->pedantic_hinting )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Too_Few_Arguments );
 | 
| +          exc->error = FT_THROW( Too_Few_Arguments );
 | 
|            goto LErrorLabel_;
 | 
|          }
 | 
|  
 | 
|          /* push zeroes onto the stack */
 | 
| -        for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ )
 | 
| -          CUR.stack[i] = 0;
 | 
| -        CUR.args = 0;
 | 
| +        for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
 | 
| +          exc->stack[i] = 0;
 | 
| +        exc->args = 0;
 | 
|        }
 | 
|  
 | 
| -      CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );
 | 
| +      exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
 | 
|  
 | 
|        /* `new_top' is the new top of the stack, after the instruction's */
 | 
|        /* execution.  `top' will be set to `new_top' after the `switch'  */
 | 
|        /* statement.                                                     */
 | 
| -      if ( CUR.new_top > CUR.stackSize )
 | 
| +      if ( exc->new_top > exc->stackSize )
 | 
|        {
 | 
| -        CUR.error = FT_THROW( Stack_Overflow );
 | 
| +        exc->error = FT_THROW( Stack_Overflow );
 | 
|          goto LErrorLabel_;
 | 
|        }
 | 
|  
 | 
| -      CUR.step_ins = TRUE;
 | 
| -      CUR.error    = FT_Err_Ok;
 | 
| +      exc->step_ins = TRUE;
 | 
| +      exc->error    = FT_Err_Ok;
 | 
|  
 | 
|  #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 | 
|  
 | 
| @@ -8316,17 +7621,17 @@
 | 
|        {
 | 
|          for ( i = 0; i < opcode_patterns; i++ )
 | 
|          {
 | 
| -          if ( opcode_pointer[i] < opcode_size[i]                 &&
 | 
| -               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
 | 
| +          if ( opcode_pointer[i] < opcode_size[i]                  &&
 | 
| +               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
 | 
|            {
 | 
|              opcode_pointer[i] += 1;
 | 
|  
 | 
|              if ( opcode_pointer[i] == opcode_size[i] )
 | 
|              {
 | 
| -              FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
 | 
| +              FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
 | 
|                            i,
 | 
| -                          CUR.face->root.family_name,
 | 
| -                          CUR.face->root.style_name ));
 | 
| +                          exc->face->root.family_name,
 | 
| +                          exc->face->root.style_name ));
 | 
|  
 | 
|                switch ( i )
 | 
|                {
 | 
| @@ -8343,15 +7648,9 @@
 | 
|  
 | 
|  #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 | 
|  
 | 
| -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
 | 
| -
 | 
|        {
 | 
| -        FT_Long*  args   = CUR.stack + CUR.args;
 | 
| -        FT_Byte   opcode = CUR.opcode;
 | 
| -
 | 
| -
 | 
| -#undef  ARRAY_BOUND_ERROR
 | 
| -#define ARRAY_BOUND_ERROR  goto Set_Invalid_Ref
 | 
| +        FT_Long*  args   = exc->stack + exc->args;
 | 
| +        FT_Byte   opcode = exc->opcode;
 | 
|  
 | 
|  
 | 
|          switch ( opcode )
 | 
| @@ -8362,580 +7661,543 @@
 | 
|          case 0x03:  /* SPvTCA x */
 | 
|          case 0x04:  /* SFvTCA y */
 | 
|          case 0x05:  /* SFvTCA x */
 | 
| -          {
 | 
| -            FT_Short  AA, BB;
 | 
| -
 | 
| -
 | 
| -            AA = (FT_Short)( ( opcode & 1 ) << 14 );
 | 
| -            BB = (FT_Short)( AA ^ 0x4000 );
 | 
| -
 | 
| -            if ( opcode < 4 )
 | 
| -            {
 | 
| -              CUR.GS.projVector.x = AA;
 | 
| -              CUR.GS.projVector.y = BB;
 | 
| -
 | 
| -              CUR.GS.dualVector.x = AA;
 | 
| -              CUR.GS.dualVector.y = BB;
 | 
| -            }
 | 
| -            else
 | 
| -            {
 | 
| -              GUESS_VECTOR( projVector );
 | 
| -            }
 | 
| -
 | 
| -            if ( ( opcode & 2 ) == 0 )
 | 
| -            {
 | 
| -              CUR.GS.freeVector.x = AA;
 | 
| -              CUR.GS.freeVector.y = BB;
 | 
| -            }
 | 
| -            else
 | 
| -            {
 | 
| -              GUESS_VECTOR( freeVector );
 | 
| -            }
 | 
| -
 | 
| -            COMPUTE_Funcs();
 | 
| -          }
 | 
| +          Ins_SxyTCA( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x06:  /* SPvTL // */
 | 
|          case 0x07:  /* SPvTL +  */
 | 
| -          DO_SPVTL
 | 
| +          Ins_SPVTL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x08:  /* SFvTL // */
 | 
|          case 0x09:  /* SFvTL +  */
 | 
| -          DO_SFVTL
 | 
| +          Ins_SFVTL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x0A:  /* SPvFS */
 | 
| -          DO_SPVFS
 | 
| +          Ins_SPVFS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x0B:  /* SFvFS */
 | 
| -          DO_SFVFS
 | 
| +          Ins_SFVFS( exc, args );
 | 
|            break;
 | 
|  
 | 
| -        case 0x0C:  /* GPV */
 | 
| -          DO_GPV
 | 
| +        case 0x0C:  /* GPv */
 | 
| +          Ins_GPV( exc, args );
 | 
|            break;
 | 
|  
 | 
| -        case 0x0D:  /* GFV */
 | 
| -          DO_GFV
 | 
| +        case 0x0D:  /* GFv */
 | 
| +          Ins_GFV( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x0E:  /* SFvTPv */
 | 
| -          DO_SFVTPV
 | 
| +          Ins_SFVTPV( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x0F:  /* ISECT  */
 | 
| -          Ins_ISECT( EXEC_ARG_ args );
 | 
| +          Ins_ISECT( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x10:  /* SRP0 */
 | 
| -          DO_SRP0
 | 
| +          Ins_SRP0( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x11:  /* SRP1 */
 | 
| -          DO_SRP1
 | 
| +          Ins_SRP1( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x12:  /* SRP2 */
 | 
| -          DO_SRP2
 | 
| +          Ins_SRP2( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x13:  /* SZP0 */
 | 
| -          Ins_SZP0( EXEC_ARG_ args );
 | 
| +          Ins_SZP0( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x14:  /* SZP1 */
 | 
| -          Ins_SZP1( EXEC_ARG_ args );
 | 
| +          Ins_SZP1( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x15:  /* SZP2 */
 | 
| -          Ins_SZP2( EXEC_ARG_ args );
 | 
| +          Ins_SZP2( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x16:  /* SZPS */
 | 
| -          Ins_SZPS( EXEC_ARG_ args );
 | 
| +          Ins_SZPS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x17:  /* SLOOP */
 | 
| -          DO_SLOOP
 | 
| +          Ins_SLOOP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x18:  /* RTG */
 | 
| -          DO_RTG
 | 
| +          Ins_RTG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x19:  /* RTHG */
 | 
| -          DO_RTHG
 | 
| +          Ins_RTHG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x1A:  /* SMD */
 | 
| -          DO_SMD
 | 
| +          Ins_SMD( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x1B:  /* ELSE */
 | 
| -          Ins_ELSE( EXEC_ARG_ args );
 | 
| +          Ins_ELSE( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x1C:  /* JMPR */
 | 
| -          DO_JMPR
 | 
| +          Ins_JMPR( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x1D:  /* SCVTCI */
 | 
| -          DO_SCVTCI
 | 
| +          Ins_SCVTCI( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x1E:  /* SSWCI */
 | 
| -          DO_SSWCI
 | 
| +          Ins_SSWCI( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x1F:  /* SSW */
 | 
| -          DO_SSW
 | 
| +          Ins_SSW( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x20:  /* DUP */
 | 
| -          DO_DUP
 | 
| +          Ins_DUP( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x21:  /* POP */
 | 
| -          /* nothing :-) */
 | 
| +          Ins_POP();
 | 
|            break;
 | 
|  
 | 
|          case 0x22:  /* CLEAR */
 | 
| -          DO_CLEAR
 | 
| +          Ins_CLEAR( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x23:  /* SWAP */
 | 
| -          DO_SWAP
 | 
| +          Ins_SWAP( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x24:  /* DEPTH */
 | 
| -          DO_DEPTH
 | 
| +          Ins_DEPTH( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x25:  /* CINDEX */
 | 
| -          DO_CINDEX
 | 
| +          Ins_CINDEX( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x26:  /* MINDEX */
 | 
| -          Ins_MINDEX( EXEC_ARG_ args );
 | 
| +          Ins_MINDEX( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x27:  /* ALIGNPTS */
 | 
| -          Ins_ALIGNPTS( EXEC_ARG_ args );
 | 
| +          Ins_ALIGNPTS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x28:  /* ???? */
 | 
| -          Ins_UNKNOWN( EXEC_ARG_ args );
 | 
| +          Ins_UNKNOWN( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x29:  /* UTP */
 | 
| -          Ins_UTP( EXEC_ARG_ args );
 | 
| +          Ins_UTP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x2A:  /* LOOPCALL */
 | 
| -          Ins_LOOPCALL( EXEC_ARG_ args );
 | 
| +          Ins_LOOPCALL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x2B:  /* CALL */
 | 
| -          Ins_CALL( EXEC_ARG_ args );
 | 
| +          Ins_CALL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x2C:  /* FDEF */
 | 
| -          Ins_FDEF( EXEC_ARG_ args );
 | 
| +          Ins_FDEF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x2D:  /* ENDF */
 | 
| -          Ins_ENDF( EXEC_ARG_ args );
 | 
| +          Ins_ENDF( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x2E:  /* MDAP */
 | 
|          case 0x2F:  /* MDAP */
 | 
| -          Ins_MDAP( EXEC_ARG_ args );
 | 
| +          Ins_MDAP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x30:  /* IUP */
 | 
|          case 0x31:  /* IUP */
 | 
| -          Ins_IUP( EXEC_ARG_ args );
 | 
| +          Ins_IUP( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x32:  /* SHP */
 | 
|          case 0x33:  /* SHP */
 | 
| -          Ins_SHP( EXEC_ARG_ args );
 | 
| +          Ins_SHP( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x34:  /* SHC */
 | 
|          case 0x35:  /* SHC */
 | 
| -          Ins_SHC( EXEC_ARG_ args );
 | 
| +          Ins_SHC( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x36:  /* SHZ */
 | 
|          case 0x37:  /* SHZ */
 | 
| -          Ins_SHZ( EXEC_ARG_ args );
 | 
| +          Ins_SHZ( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x38:  /* SHPIX */
 | 
| -          Ins_SHPIX( EXEC_ARG_ args );
 | 
| +          Ins_SHPIX( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x39:  /* IP    */
 | 
| -          Ins_IP( EXEC_ARG_ args );
 | 
| +          Ins_IP( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x3A:  /* MSIRP */
 | 
|          case 0x3B:  /* MSIRP */
 | 
| -          Ins_MSIRP( EXEC_ARG_ args );
 | 
| +          Ins_MSIRP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x3C:  /* AlignRP */
 | 
| -          Ins_ALIGNRP( EXEC_ARG_ args );
 | 
| +          Ins_ALIGNRP( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x3D:  /* RTDG */
 | 
| -          DO_RTDG
 | 
| +          Ins_RTDG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x3E:  /* MIAP */
 | 
|          case 0x3F:  /* MIAP */
 | 
| -          Ins_MIAP( EXEC_ARG_ args );
 | 
| +          Ins_MIAP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x40:  /* NPUSHB */
 | 
| -          Ins_NPUSHB( EXEC_ARG_ args );
 | 
| +          Ins_NPUSHB( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x41:  /* NPUSHW */
 | 
| -          Ins_NPUSHW( EXEC_ARG_ args );
 | 
| +          Ins_NPUSHW( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x42:  /* WS */
 | 
| -          DO_WS
 | 
| -          break;
 | 
| -
 | 
| -      Set_Invalid_Ref:
 | 
| -            CUR.error = FT_THROW( Invalid_Reference );
 | 
| +          Ins_WS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x43:  /* RS */
 | 
| -          DO_RS
 | 
| +          Ins_RS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x44:  /* WCVTP */
 | 
| -          DO_WCVTP
 | 
| +          Ins_WCVTP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x45:  /* RCVT */
 | 
| -          DO_RCVT
 | 
| +          Ins_RCVT( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x46:  /* GC */
 | 
|          case 0x47:  /* GC */
 | 
| -          Ins_GC( EXEC_ARG_ args );
 | 
| +          Ins_GC( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x48:  /* SCFS */
 | 
| -          Ins_SCFS( EXEC_ARG_ args );
 | 
| +          Ins_SCFS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x49:  /* MD */
 | 
|          case 0x4A:  /* MD */
 | 
| -          Ins_MD( EXEC_ARG_ args );
 | 
| +          Ins_MD( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x4B:  /* MPPEM */
 | 
| -          DO_MPPEM
 | 
| +          Ins_MPPEM( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x4C:  /* MPS */
 | 
| -          DO_MPS
 | 
| +          Ins_MPS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x4D:  /* FLIPON */
 | 
| -          DO_FLIPON
 | 
| +          Ins_FLIPON( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x4E:  /* FLIPOFF */
 | 
| -          DO_FLIPOFF
 | 
| +          Ins_FLIPOFF( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x4F:  /* DEBUG */
 | 
| -          DO_DEBUG
 | 
| +          Ins_DEBUG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x50:  /* LT */
 | 
| -          DO_LT
 | 
| +          Ins_LT( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x51:  /* LTEQ */
 | 
| -          DO_LTEQ
 | 
| +          Ins_LTEQ( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x52:  /* GT */
 | 
| -          DO_GT
 | 
| +          Ins_GT( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x53:  /* GTEQ */
 | 
| -          DO_GTEQ
 | 
| +          Ins_GTEQ( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x54:  /* EQ */
 | 
| -          DO_EQ
 | 
| +          Ins_EQ( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x55:  /* NEQ */
 | 
| -          DO_NEQ
 | 
| +          Ins_NEQ( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x56:  /* ODD */
 | 
| -          DO_ODD
 | 
| +          Ins_ODD( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x57:  /* EVEN */
 | 
| -          DO_EVEN
 | 
| +          Ins_EVEN( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x58:  /* IF */
 | 
| -          Ins_IF( EXEC_ARG_ args );
 | 
| +          Ins_IF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x59:  /* EIF */
 | 
| -          /* do nothing */
 | 
| +          Ins_EIF();
 | 
|            break;
 | 
|  
 | 
|          case 0x5A:  /* AND */
 | 
| -          DO_AND
 | 
| +          Ins_AND( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x5B:  /* OR */
 | 
| -          DO_OR
 | 
| +          Ins_OR( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x5C:  /* NOT */
 | 
| -          DO_NOT
 | 
| +          Ins_NOT( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x5D:  /* DELTAP1 */
 | 
| -          Ins_DELTAP( EXEC_ARG_ args );
 | 
| +          Ins_DELTAP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x5E:  /* SDB */
 | 
| -          DO_SDB
 | 
| +          Ins_SDB( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x5F:  /* SDS */
 | 
| -          DO_SDS
 | 
| +          Ins_SDS( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x60:  /* ADD */
 | 
| -          DO_ADD
 | 
| +          Ins_ADD( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x61:  /* SUB */
 | 
| -          DO_SUB
 | 
| +          Ins_SUB( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x62:  /* DIV */
 | 
| -          DO_DIV
 | 
| +          Ins_DIV( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x63:  /* MUL */
 | 
| -          DO_MUL
 | 
| +          Ins_MUL( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x64:  /* ABS */
 | 
| -          DO_ABS
 | 
| +          Ins_ABS( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x65:  /* NEG */
 | 
| -          DO_NEG
 | 
| +          Ins_NEG( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x66:  /* FLOOR */
 | 
| -          DO_FLOOR
 | 
| +          Ins_FLOOR( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x67:  /* CEILING */
 | 
| -          DO_CEILING
 | 
| +          Ins_CEILING( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x68:  /* ROUND */
 | 
|          case 0x69:  /* ROUND */
 | 
|          case 0x6A:  /* ROUND */
 | 
|          case 0x6B:  /* ROUND */
 | 
| -          DO_ROUND
 | 
| +          Ins_ROUND( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x6C:  /* NROUND */
 | 
|          case 0x6D:  /* NROUND */
 | 
|          case 0x6E:  /* NRRUND */
 | 
|          case 0x6F:  /* NROUND */
 | 
| -          DO_NROUND
 | 
| +          Ins_NROUND( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x70:  /* WCVTF */
 | 
| -          DO_WCVTF
 | 
| +          Ins_WCVTF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x71:  /* DELTAP2 */
 | 
|          case 0x72:  /* DELTAP3 */
 | 
| -          Ins_DELTAP( EXEC_ARG_ args );
 | 
| +          Ins_DELTAP( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x73:  /* DELTAC0 */
 | 
|          case 0x74:  /* DELTAC1 */
 | 
|          case 0x75:  /* DELTAC2 */
 | 
| -          Ins_DELTAC( EXEC_ARG_ args );
 | 
| +          Ins_DELTAC( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x76:  /* SROUND */
 | 
| -          DO_SROUND
 | 
| +          Ins_SROUND( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x77:  /* S45Round */
 | 
| -          DO_S45ROUND
 | 
| +          Ins_S45ROUND( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x78:  /* JROT */
 | 
| -          DO_JROT
 | 
| +          Ins_JROT( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x79:  /* JROF */
 | 
| -          DO_JROF
 | 
| +          Ins_JROF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x7A:  /* ROFF */
 | 
| -          DO_ROFF
 | 
| +          Ins_ROFF( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x7B:  /* ???? */
 | 
| -          Ins_UNKNOWN( EXEC_ARG_ args );
 | 
| +          Ins_UNKNOWN( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x7C:  /* RUTG */
 | 
| -          DO_RUTG
 | 
| +          Ins_RUTG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x7D:  /* RDTG */
 | 
| -          DO_RDTG
 | 
| +          Ins_RDTG( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x7E:  /* SANGW */
 | 
| -        case 0x7F:  /* AA    */
 | 
| -          /* nothing - obsolete */
 | 
| +          Ins_SANGW();
 | 
| +          break;
 | 
| +
 | 
| +        case 0x7F:  /* AA */
 | 
| +          Ins_AA();
 | 
|            break;
 | 
|  
 | 
|          case 0x80:  /* FLIPPT */
 | 
| -          Ins_FLIPPT( EXEC_ARG_ args );
 | 
| +          Ins_FLIPPT( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x81:  /* FLIPRGON */
 | 
| -          Ins_FLIPRGON( EXEC_ARG_ args );
 | 
| +          Ins_FLIPRGON( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x82:  /* FLIPRGOFF */
 | 
| -          Ins_FLIPRGOFF( EXEC_ARG_ args );
 | 
| +          Ins_FLIPRGOFF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x83:  /* UNKNOWN */
 | 
|          case 0x84:  /* UNKNOWN */
 | 
| -          Ins_UNKNOWN( EXEC_ARG_ args );
 | 
| +          Ins_UNKNOWN( exc );
 | 
|            break;
 | 
|  
 | 
|          case 0x85:  /* SCANCTRL */
 | 
| -          Ins_SCANCTRL( EXEC_ARG_ args );
 | 
| +          Ins_SCANCTRL( exc, args );
 | 
|            break;
 | 
|  
 | 
| -        case 0x86:  /* SDPVTL */
 | 
| -        case 0x87:  /* SDPVTL */
 | 
| -          Ins_SDPVTL( EXEC_ARG_ args );
 | 
| +        case 0x86:  /* SDPvTL */
 | 
| +        case 0x87:  /* SDPvTL */
 | 
| +          Ins_SDPVTL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x88:  /* GETINFO */
 | 
| -          Ins_GETINFO( EXEC_ARG_ args );
 | 
| +          Ins_GETINFO( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x89:  /* IDEF */
 | 
| -          Ins_IDEF( EXEC_ARG_ args );
 | 
| +          Ins_IDEF( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8A:  /* ROLL */
 | 
| -          Ins_ROLL( EXEC_ARG_ args );
 | 
| +          Ins_ROLL( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8B:  /* MAX */
 | 
| -          DO_MAX
 | 
| +          Ins_MAX( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8C:  /* MIN */
 | 
| -          DO_MIN
 | 
| +          Ins_MIN( args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8D:  /* SCANTYPE */
 | 
| -          Ins_SCANTYPE( EXEC_ARG_ args );
 | 
| +          Ins_SCANTYPE( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8E:  /* INSTCTRL */
 | 
| -          Ins_INSTCTRL( EXEC_ARG_ args );
 | 
| +          Ins_INSTCTRL( exc, args );
 | 
|            break;
 | 
|  
 | 
|          case 0x8F:
 | 
| -          Ins_UNKNOWN( EXEC_ARG_ args );
 | 
| +          Ins_UNKNOWN( exc );
 | 
|            break;
 | 
|  
 | 
|          default:
 | 
|            if ( opcode >= 0xE0 )
 | 
| -            Ins_MIRP( EXEC_ARG_ args );
 | 
| +            Ins_MIRP( exc, args );
 | 
|            else if ( opcode >= 0xC0 )
 | 
| -            Ins_MDRP( EXEC_ARG_ args );
 | 
| +            Ins_MDRP( exc, args );
 | 
|            else if ( opcode >= 0xB8 )
 | 
| -            Ins_PUSHW( EXEC_ARG_ args );
 | 
| +            Ins_PUSHW( exc, args );
 | 
|            else if ( opcode >= 0xB0 )
 | 
| -            Ins_PUSHB( EXEC_ARG_ args );
 | 
| +            Ins_PUSHB( exc, args );
 | 
|            else
 | 
| -            Ins_UNKNOWN( EXEC_ARG_ args );
 | 
| +            Ins_UNKNOWN( exc );
 | 
|          }
 | 
| -
 | 
|        }
 | 
|  
 | 
| -#else
 | 
| -
 | 
| -      Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
 | 
| -
 | 
| -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
 | 
| -
 | 
| -      if ( CUR.error )
 | 
| +      if ( exc->error )
 | 
|        {
 | 
| -        switch ( CUR.error )
 | 
| +        switch ( exc->error )
 | 
|          {
 | 
|            /* looking for redefined instructions */
 | 
|          case FT_ERR( Invalid_Opcode ):
 | 
|            {
 | 
| -            TT_DefRecord*  def   = CUR.IDefs;
 | 
| -            TT_DefRecord*  limit = def + CUR.numIDefs;
 | 
| +            TT_DefRecord*  def   = exc->IDefs;
 | 
| +            TT_DefRecord*  limit = def + exc->numIDefs;
 | 
|  
 | 
|  
 | 
|              for ( ; def < limit; def++ )
 | 
|              {
 | 
| -              if ( def->active && CUR.opcode == (FT_Byte)def->opc )
 | 
| +              if ( def->active && exc->opcode == (FT_Byte)def->opc )
 | 
|                {
 | 
|                  TT_CallRec*  callrec;
 | 
|  
 | 
|  
 | 
| -                if ( CUR.callTop >= CUR.callSize )
 | 
| +                if ( exc->callTop >= exc->callSize )
 | 
|                  {
 | 
| -                  CUR.error = FT_THROW( Invalid_Reference );
 | 
| +                  exc->error = FT_THROW( Invalid_Reference );
 | 
|                    goto LErrorLabel_;
 | 
|                  }
 | 
|  
 | 
| -                callrec = &CUR.callStack[CUR.callTop];
 | 
| +                callrec = &exc->callStack[exc->callTop];
 | 
|  
 | 
| -                callrec->Caller_Range = CUR.curRange;
 | 
| -                callrec->Caller_IP    = CUR.IP + 1;
 | 
| +                callrec->Caller_Range = exc->curRange;
 | 
| +                callrec->Caller_IP    = exc->IP + 1;
 | 
|                  callrec->Cur_Count    = 1;
 | 
|                  callrec->Def          = def;
 | 
|  
 | 
| -                if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
 | 
| +                if ( Ins_Goto_CodeRange( exc,
 | 
| +                                         def->range,
 | 
| +                                         def->start ) == FAILURE )
 | 
|                    goto LErrorLabel_;
 | 
|  
 | 
|                  goto LSuiteLabel_;
 | 
| @@ -8943,7 +8205,7 @@
 | 
|              }
 | 
|            }
 | 
|  
 | 
| -          CUR.error = FT_THROW( Invalid_Opcode );
 | 
| +          exc->error = FT_THROW( Invalid_Opcode );
 | 
|            goto LErrorLabel_;
 | 
|  
 | 
|  #if 0
 | 
| @@ -8961,10 +8223,10 @@
 | 
|          }
 | 
|        }
 | 
|  
 | 
| -      CUR.top = CUR.new_top;
 | 
| +      exc->top = exc->new_top;
 | 
|  
 | 
| -      if ( CUR.step_ins )
 | 
| -        CUR.IP += CUR.length;
 | 
| +      if ( exc->step_ins )
 | 
| +        exc->IP += exc->length;
 | 
|  
 | 
|        /* increment instruction counter and check if we didn't */
 | 
|        /* run this program for too long (e.g. infinite loops). */
 | 
| @@ -8972,48 +8234,38 @@
 | 
|          return FT_THROW( Execution_Too_Long );
 | 
|  
 | 
|      LSuiteLabel_:
 | 
| -      if ( CUR.IP >= CUR.codeSize )
 | 
| +      if ( exc->IP >= exc->codeSize )
 | 
|        {
 | 
| -        if ( CUR.callTop > 0 )
 | 
| +        if ( exc->callTop > 0 )
 | 
|          {
 | 
| -          CUR.error = FT_THROW( Code_Overflow );
 | 
| +          exc->error = FT_THROW( Code_Overflow );
 | 
|            goto LErrorLabel_;
 | 
|          }
 | 
|          else
 | 
|            goto LNo_Error_;
 | 
|        }
 | 
| -    } while ( !CUR.instruction_trap );
 | 
| +    } while ( !exc->instruction_trap );
 | 
|  
 | 
|    LNo_Error_:
 | 
| -
 | 
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
 | 
| -    *exc = cur;
 | 
| -#endif
 | 
| -
 | 
|      return FT_Err_Ok;
 | 
|  
 | 
|    LErrorCodeOverflow_:
 | 
| -    CUR.error = FT_THROW( Code_Overflow );
 | 
| +    exc->error = FT_THROW( Code_Overflow );
 | 
|  
 | 
|    LErrorLabel_:
 | 
| -
 | 
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
 | 
| -    *exc = cur;
 | 
| -#endif
 | 
| -
 | 
|      /* If any errors have occurred, function tables may be broken. */
 | 
|      /* Force a re-execution of `prep' and `fpgm' tables if no      */
 | 
|      /* bytecode debugger is run.                                   */
 | 
| -    if ( CUR.error
 | 
| -         && !CUR.instruction_trap
 | 
| -         && CUR.curRange == tt_coderange_glyph )
 | 
| +    if ( exc->error                          &&
 | 
| +         !exc->instruction_trap              &&
 | 
| +         exc->curRange == tt_coderange_glyph )
 | 
|      {
 | 
| -      FT_TRACE1(( "  The interpreter returned error 0x%x\n", CUR.error ));
 | 
| +      FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
 | 
|        exc->size->bytecode_ready = -1;
 | 
|        exc->size->cvt_ready      = -1;
 | 
|      }
 | 
|  
 | 
| -    return CUR.error;
 | 
| +    return exc->error;
 | 
|    }
 | 
|  
 | 
|  
 | 
| 
 |