[SDK] One step further towards ReactOS source code tree restructure: the sdk folder...
[reactos.git] / reactos / lib / 3rdparty / freetype / src / truetype / ttinterp.c
diff --git a/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c b/reactos/lib/3rdparty/freetype/src/truetype/ttinterp.c
deleted file mode 100644 (file)
index ccbb1d7..0000000
+++ /dev/null
@@ -1,8043 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ttinterp.c                                                             */
-/*                                                                         */
-/*    TrueType bytecode interpreter (body).                                */
-/*                                                                         */
-/*  Copyright 1996-2016 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      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-/* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */
-/* issues; many thanks!                                                */
-
-
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_TRIGONOMETRY_H
-#include FT_SYSTEM_H
-#include FT_TRUETYPE_DRIVER_H
-
-#include "ttinterp.h"
-#include "tterrors.h"
-#include "ttsubpix.h"
-
-
-#ifdef TT_USE_BYTECODE_INTERPRETER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttinterp
-
-
-#define SUBPIXEL_HINTING                                                     \
-          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
-            TT_INTERPRETER_VERSION_38 )
-
-
-#define PROJECT( v1, v2 )                                                \
-          exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define DUALPROJ( v1, v2 )                                                \
-          exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define FAST_PROJECT( v )                          \
-          exc->func_project( exc, (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)( TT_ExecContext  exc,
-                                          FT_Long*        args );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Two simple bounds-checking macros.                                    */
-  /*                                                                       */
-#define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )
-#define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )
-
-
-#undef  SUCCESS
-#define SUCCESS  0
-
-#undef  FAILURE
-#define FAILURE  1
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                        CODERANGE FUNCTIONS                            */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Goto_CodeRange                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Switches to a new code range (updates the code related elements in */
-  /*    `exec', and `IP').                                                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    range :: The new execution code range.                             */
-  /*                                                                       */
-  /*    IP    :: The new IP in the new code range.                         */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    exec  :: The target execution context.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( void )
-  TT_Goto_CodeRange( TT_ExecContext  exec,
-                     FT_Int          range,
-                     FT_Long         IP )
-  {
-    TT_CodeRange*  coderange;
-
-
-    FT_ASSERT( range >= 1 && range <= 3 );
-
-    coderange = &exec->codeRangeTable[range - 1];
-
-    FT_ASSERT( coderange->base != NULL );
-
-    /* NOTE: Because the last instruction of a program may be a CALL */
-    /*       which will return to the first byte *after* the code    */
-    /*       range, we test for IP <= Size instead of IP < Size.     */
-    /*                                                               */
-    FT_ASSERT( IP <= coderange->size );
-
-    exec->code     = coderange->base;
-    exec->codeSize = coderange->size;
-    exec->IP       = IP;
-    exec->curRange = range;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Set_CodeRange                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a code range.                                                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    range  :: The code range index.                                    */
-  /*                                                                       */
-  /*    base   :: The new code base.                                       */
-  /*                                                                       */
-  /*    length :: The range size in bytes.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    exec   :: The target execution context.                            */
-  /*                                                                       */
-  FT_LOCAL_DEF( void )
-  TT_Set_CodeRange( TT_ExecContext  exec,
-                    FT_Int          range,
-                    void*           base,
-                    FT_Long         length )
-  {
-    FT_ASSERT( range >= 1 && range <= 3 );
-
-    exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
-    exec->codeRangeTable[range - 1].size = length;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Clear_CodeRange                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Clears a code range.                                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    range :: The code range index.                                     */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    exec  :: The target execution context.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( void )
-  TT_Clear_CodeRange( TT_ExecContext  exec,
-                      FT_Int          range )
-  {
-    FT_ASSERT( range >= 1 && range <= 3 );
-
-    exec->codeRangeTable[range - 1].base = NULL;
-    exec->codeRangeTable[range - 1].size = 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                   EXECUTION CONTEXT ROUTINES                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Done_Context                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Destroys a given context.                                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    exec   :: A handle to the target execution context.                */
-  /*                                                                       */
-  /*    memory :: A handle to the parent memory object.                    */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only the glyph loader and debugger should call this function.      */
-  /*                                                                       */
-  FT_LOCAL_DEF( void )
-  TT_Done_Context( TT_ExecContext  exec )
-  {
-    FT_Memory  memory = exec->memory;
-
-
-    /* points zone */
-    exec->maxPoints   = 0;
-    exec->maxContours = 0;
-
-    /* free stack */
-    FT_FREE( exec->stack );
-    exec->stackSize = 0;
-
-    /* free call stack */
-    FT_FREE( exec->callStack );
-    exec->callSize = 0;
-    exec->callTop  = 0;
-
-    /* free glyph code range */
-    FT_FREE( exec->glyphIns );
-    exec->glyphSize = 0;
-
-    exec->size = NULL;
-    exec->face = NULL;
-
-    FT_FREE( exec );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Init_Context                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a context object.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    memory :: A handle to the parent memory object.                    */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    exec   :: A handle to the target execution context.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  static FT_Error
-  Init_Context( TT_ExecContext  exec,
-                FT_Memory       memory )
-  {
-    FT_Error  error;
-
-
-    FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));
-
-    exec->memory   = memory;
-    exec->callSize = 32;
-
-    if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )
-      goto Fail_Memory;
-
-    /* all values in the context are set to 0 already, but this is */
-    /* here as a remainder                                         */
-    exec->maxPoints   = 0;
-    exec->maxContours = 0;
-
-    exec->stackSize = 0;
-    exec->glyphSize = 0;
-
-    exec->stack     = NULL;
-    exec->glyphIns  = NULL;
-
-    exec->face = NULL;
-    exec->size = NULL;
-
-    return FT_Err_Ok;
-
-  Fail_Memory:
-    FT_ERROR(( "Init_Context: not enough memory for %p\n", exec ));
-    TT_Done_Context( exec );
-
-    return error;
- }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Update_Max                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Checks the size of a buffer and reallocates it if necessary.       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    memory     :: A handle to the parent memory object.                */
-  /*                                                                       */
-  /*    multiplier :: The size in bytes of each element in the buffer.     */
-  /*                                                                       */
-  /*    new_max    :: The new capacity (size) of the buffer.               */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size       :: The address of the buffer's current size expressed   */
-  /*                  in elements.                                         */
-  /*                                                                       */
-  /*    buff       :: The address of the buffer base pointer.              */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  Update_Max( FT_Memory  memory,
-              FT_ULong*  size,
-              FT_ULong   multiplier,
-              void*      _pbuff,
-              FT_ULong   new_max )
-  {
-    FT_Error  error;
-    void**    pbuff = (void**)_pbuff;
-
-
-    if ( *size < new_max )
-    {
-      if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
-        return error;
-      *size = new_max;
-    }
-
-    return FT_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Load_Context                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Prepare an execution context for glyph hinting.                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face :: A handle to the source face object.                        */
-  /*                                                                       */
-  /*    size :: A handle to the source size object.                        */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    exec :: A handle to the target execution context.                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only the glyph loader and debugger should call this function.      */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  TT_Load_Context( TT_ExecContext  exec,
-                   TT_Face         face,
-                   TT_Size         size )
-  {
-    FT_Int          i;
-    FT_ULong        tmp;
-    TT_MaxProfile*  maxp;
-    FT_Error        error;
-
-
-    exec->face = face;
-    maxp       = &face->max_profile;
-    exec->size = size;
-
-    if ( size )
-    {
-      exec->numFDefs   = size->num_function_defs;
-      exec->maxFDefs   = size->max_function_defs;
-      exec->numIDefs   = size->num_instruction_defs;
-      exec->maxIDefs   = size->max_instruction_defs;
-      exec->FDefs      = size->function_defs;
-      exec->IDefs      = size->instruction_defs;
-      exec->tt_metrics = size->ttmetrics;
-      exec->metrics    = size->metrics;
-
-      exec->maxFunc    = size->max_func;
-      exec->maxIns     = size->max_ins;
-
-      for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
-        exec->codeRangeTable[i] = size->codeRangeTable[i];
-
-      /* set graphics state */
-      exec->GS = size->GS;
-
-      exec->cvtSize = size->cvt_size;
-      exec->cvt     = size->cvt;
-
-      exec->storeSize = size->storage_size;
-      exec->storage   = size->storage;
-
-      exec->twilight  = size->twilight;
-
-      /* In case of multi-threading it can happen that the old size object */
-      /* no longer exists, thus we must clear all glyph zone references.   */
-      ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) );
-      exec->zp1 = exec->zp0;
-      exec->zp2 = exec->zp0;
-    }
-
-    /* XXX: We reserve a little more elements on the stack to deal safely */
-    /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
-    tmp = (FT_ULong)exec->stackSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_F26Dot6 ),
-                        (void*)&exec->stack,
-                        maxp->maxStackElements + 32 );
-    exec->stackSize = (FT_Long)tmp;
-    if ( error )
-      return error;
-
-    tmp = exec->glyphSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_Byte ),
-                        (void*)&exec->glyphIns,
-                        maxp->maxSizeOfInstructions );
-    exec->glyphSize = (FT_UShort)tmp;
-    if ( error )
-      return error;
-
-    exec->pts.n_points   = 0;
-    exec->pts.n_contours = 0;
-
-    exec->zp1 = exec->pts;
-    exec->zp2 = exec->pts;
-    exec->zp0 = exec->pts;
-
-    exec->instruction_trap = FALSE;
-
-    return FT_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Save_Context                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Saves the code ranges in a `size' object.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    exec :: A handle to the source execution context.                  */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only the glyph loader and debugger should call this function.      */
-  /*                                                                       */
-  FT_LOCAL_DEF( void )
-  TT_Save_Context( TT_ExecContext  exec,
-                   TT_Size         size )
-  {
-    FT_Int  i;
-
-
-    /* XXX: Will probably disappear soon with all the code range */
-    /*      management, which is now rather obsolete.            */
-    /*                                                           */
-    size->num_function_defs    = exec->numFDefs;
-    size->num_instruction_defs = exec->numIDefs;
-
-    size->max_func = exec->maxFunc;
-    size->max_ins  = exec->maxIns;
-
-    for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
-      size->codeRangeTable[i] = exec->codeRangeTable[i];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Run_Context                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Executes one or more instructions in the execution context.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    debug :: A Boolean flag.  If set, the function sets some internal  */
-  /*             variables and returns immediately, otherwise TT_RunIns()  */
-  /*             is called.                                                */
-  /*                                                                       */
-  /*             This is commented out currently.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    exec  :: A handle to the target execution context.                 */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    TrueType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  TT_Run_Context( TT_ExecContext  exec )
-  {
-    TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
-
-    exec->zp0 = exec->pts;
-    exec->zp1 = exec->pts;
-    exec->zp2 = exec->pts;
-
-    exec->GS.gep0 = 1;
-    exec->GS.gep1 = 1;
-    exec->GS.gep2 = 1;
-
-    exec->GS.projVector.x = 0x4000;
-    exec->GS.projVector.y = 0x0000;
-
-    exec->GS.freeVector = exec->GS.projVector;
-    exec->GS.dualVector = exec->GS.projVector;
-
-    exec->GS.round_state = 1;
-    exec->GS.loop        = 1;
-
-    /* some glyphs leave something on the stack. so we clean it */
-    /* before a new execution.                                  */
-    exec->top     = 0;
-    exec->callTop = 0;
-
-    return exec->face->interpreter( exec );
-  }
-
-
-  /* The default value for `scan_control' is documented as FALSE in the */
-  /* TrueType specification.  This is confusing since it implies a      */
-  /* Boolean value.  However, this is not the case, thus both the       */
-  /* default values of our `scan_type' and `scan_control' fields (which */
-  /* the documentation's `scan_control' variable is split into) are     */
-  /* zero.                                                              */
-
-  const TT_GraphicsState  tt_default_graphics_state =
-  {
-    0, 0, 0,
-    { 0x4000, 0 },
-    { 0x4000, 0 },
-    { 0x4000, 0 },
-
-    1, 64, 1,
-    TRUE, 68, 0, 0, 9, 3,
-    0, FALSE, 0, 1, 1, 1
-  };
-
-
-  /* documentation is in ttinterp.h */
-
-  FT_EXPORT_DEF( TT_ExecContext )
-  TT_New_Context( TT_Driver  driver )
-  {
-    FT_Memory  memory;
-    FT_Error   error;
-
-    TT_ExecContext  exec = NULL;
-
-
-    if ( !driver )
-      goto Fail;
-
-    memory = driver->root.root.memory;
-
-    /* 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;
-
-    return exec;
-
-  Fail:
-    return NULL;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Before an opcode is executed, the interpreter verifies that there are */
-  /* enough arguments on the stack, with the help of the `Pop_Push_Count'  */
-  /* table.                                                                */
-  /*                                                                       */
-  /* For each opcode, the first column gives the number of arguments that  */
-  /* are popped from the stack; the second one gives the number of those   */
-  /* that are pushed in result.                                            */
-  /*                                                                       */
-  /* Opcodes which have a varying number of parameters in the data stream  */
-  /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */
-  /* the `opcode_length' table, and the value in `Pop_Push_Count' is set   */
-  /* to zero.                                                              */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#undef  PACK
-#define PACK( x, y )  ( ( x << 4 ) | y )
-
-
-  static
-  const FT_Byte  Pop_Push_Count[256] =
-  {
-    /* opcodes are gathered in groups of 16 */
-    /* please keep the spaces as they are   */
-
-    /*  SVTCA  y  */  PACK( 0, 0 ),
-    /*  SVTCA  x  */  PACK( 0, 0 ),
-    /*  SPvTCA y  */  PACK( 0, 0 ),
-    /*  SPvTCA x  */  PACK( 0, 0 ),
-    /*  SFvTCA y  */  PACK( 0, 0 ),
-    /*  SFvTCA x  */  PACK( 0, 0 ),
-    /*  SPvTL //  */  PACK( 2, 0 ),
-    /*  SPvTL +   */  PACK( 2, 0 ),
-    /*  SFvTL //  */  PACK( 2, 0 ),
-    /*  SFvTL +   */  PACK( 2, 0 ),
-    /*  SPvFS     */  PACK( 2, 0 ),
-    /*  SFvFS     */  PACK( 2, 0 ),
-    /*  GPv       */  PACK( 0, 2 ),
-    /*  GFv       */  PACK( 0, 2 ),
-    /*  SFvTPv    */  PACK( 0, 0 ),
-    /*  ISECT     */  PACK( 5, 0 ),
-
-    /*  SRP0      */  PACK( 1, 0 ),
-    /*  SRP1      */  PACK( 1, 0 ),
-    /*  SRP2      */  PACK( 1, 0 ),
-    /*  SZP0      */  PACK( 1, 0 ),
-    /*  SZP1      */  PACK( 1, 0 ),
-    /*  SZP2      */  PACK( 1, 0 ),
-    /*  SZPS      */  PACK( 1, 0 ),
-    /*  SLOOP     */  PACK( 1, 0 ),
-    /*  RTG       */  PACK( 0, 0 ),
-    /*  RTHG      */  PACK( 0, 0 ),
-    /*  SMD       */  PACK( 1, 0 ),
-    /*  ELSE      */  PACK( 0, 0 ),
-    /*  JMPR      */  PACK( 1, 0 ),
-    /*  SCvTCi    */  PACK( 1, 0 ),
-    /*  SSwCi     */  PACK( 1, 0 ),
-    /*  SSW       */  PACK( 1, 0 ),
-
-    /*  DUP       */  PACK( 1, 2 ),
-    /*  POP       */  PACK( 1, 0 ),
-    /*  CLEAR     */  PACK( 0, 0 ),
-    /*  SWAP      */  PACK( 2, 2 ),
-    /*  DEPTH     */  PACK( 0, 1 ),
-    /*  CINDEX    */  PACK( 1, 1 ),
-    /*  MINDEX    */  PACK( 1, 0 ),
-    /*  AlignPTS  */  PACK( 2, 0 ),
-    /*  INS_$28   */  PACK( 0, 0 ),
-    /*  UTP       */  PACK( 1, 0 ),
-    /*  LOOPCALL  */  PACK( 2, 0 ),
-    /*  CALL      */  PACK( 1, 0 ),
-    /*  FDEF      */  PACK( 1, 0 ),
-    /*  ENDF      */  PACK( 0, 0 ),
-    /*  MDAP[0]   */  PACK( 1, 0 ),
-    /*  MDAP[1]   */  PACK( 1, 0 ),
-
-    /*  IUP[0]    */  PACK( 0, 0 ),
-    /*  IUP[1]    */  PACK( 0, 0 ),
-    /*  SHP[0]    */  PACK( 0, 0 ),
-    /*  SHP[1]    */  PACK( 0, 0 ),
-    /*  SHC[0]    */  PACK( 1, 0 ),
-    /*  SHC[1]    */  PACK( 1, 0 ),
-    /*  SHZ[0]    */  PACK( 1, 0 ),
-    /*  SHZ[1]    */  PACK( 1, 0 ),
-    /*  SHPIX     */  PACK( 1, 0 ),
-    /*  IP        */  PACK( 0, 0 ),
-    /*  MSIRP[0]  */  PACK( 2, 0 ),
-    /*  MSIRP[1]  */  PACK( 2, 0 ),
-    /*  AlignRP   */  PACK( 0, 0 ),
-    /*  RTDG      */  PACK( 0, 0 ),
-    /*  MIAP[0]   */  PACK( 2, 0 ),
-    /*  MIAP[1]   */  PACK( 2, 0 ),
-
-    /*  NPushB    */  PACK( 0, 0 ),
-    /*  NPushW    */  PACK( 0, 0 ),
-    /*  WS        */  PACK( 2, 0 ),
-    /*  RS        */  PACK( 1, 1 ),
-    /*  WCvtP     */  PACK( 2, 0 ),
-    /*  RCvt      */  PACK( 1, 1 ),
-    /*  GC[0]     */  PACK( 1, 1 ),
-    /*  GC[1]     */  PACK( 1, 1 ),
-    /*  SCFS      */  PACK( 2, 0 ),
-    /*  MD[0]     */  PACK( 2, 1 ),
-    /*  MD[1]     */  PACK( 2, 1 ),
-    /*  MPPEM     */  PACK( 0, 1 ),
-    /*  MPS       */  PACK( 0, 1 ),
-    /*  FlipON    */  PACK( 0, 0 ),
-    /*  FlipOFF   */  PACK( 0, 0 ),
-    /*  DEBUG     */  PACK( 1, 0 ),
-
-    /*  LT        */  PACK( 2, 1 ),
-    /*  LTEQ      */  PACK( 2, 1 ),
-    /*  GT        */  PACK( 2, 1 ),
-    /*  GTEQ      */  PACK( 2, 1 ),
-    /*  EQ        */  PACK( 2, 1 ),
-    /*  NEQ       */  PACK( 2, 1 ),
-    /*  ODD       */  PACK( 1, 1 ),
-    /*  EVEN      */  PACK( 1, 1 ),
-    /*  IF        */  PACK( 1, 0 ),
-    /*  EIF       */  PACK( 0, 0 ),
-    /*  AND       */  PACK( 2, 1 ),
-    /*  OR        */  PACK( 2, 1 ),
-    /*  NOT       */  PACK( 1, 1 ),
-    /*  DeltaP1   */  PACK( 1, 0 ),
-    /*  SDB       */  PACK( 1, 0 ),
-    /*  SDS       */  PACK( 1, 0 ),
-
-    /*  ADD       */  PACK( 2, 1 ),
-    /*  SUB       */  PACK( 2, 1 ),
-    /*  DIV       */  PACK( 2, 1 ),
-    /*  MUL       */  PACK( 2, 1 ),
-    /*  ABS       */  PACK( 1, 1 ),
-    /*  NEG       */  PACK( 1, 1 ),
-    /*  FLOOR     */  PACK( 1, 1 ),
-    /*  CEILING   */  PACK( 1, 1 ),
-    /*  ROUND[0]  */  PACK( 1, 1 ),
-    /*  ROUND[1]  */  PACK( 1, 1 ),
-    /*  ROUND[2]  */  PACK( 1, 1 ),
-    /*  ROUND[3]  */  PACK( 1, 1 ),
-    /*  NROUND[0] */  PACK( 1, 1 ),
-    /*  NROUND[1] */  PACK( 1, 1 ),
-    /*  NROUND[2] */  PACK( 1, 1 ),
-    /*  NROUND[3] */  PACK( 1, 1 ),
-
-    /*  WCvtF     */  PACK( 2, 0 ),
-    /*  DeltaP2   */  PACK( 1, 0 ),
-    /*  DeltaP3   */  PACK( 1, 0 ),
-    /*  DeltaCn[0] */ PACK( 1, 0 ),
-    /*  DeltaCn[1] */ PACK( 1, 0 ),
-    /*  DeltaCn[2] */ PACK( 1, 0 ),
-    /*  SROUND    */  PACK( 1, 0 ),
-    /*  S45Round  */  PACK( 1, 0 ),
-    /*  JROT      */  PACK( 2, 0 ),
-    /*  JROF      */  PACK( 2, 0 ),
-    /*  ROFF      */  PACK( 0, 0 ),
-    /*  INS_$7B   */  PACK( 0, 0 ),
-    /*  RUTG      */  PACK( 0, 0 ),
-    /*  RDTG      */  PACK( 0, 0 ),
-    /*  SANGW     */  PACK( 1, 0 ),
-    /*  AA        */  PACK( 1, 0 ),
-
-    /*  FlipPT    */  PACK( 0, 0 ),
-    /*  FlipRgON  */  PACK( 2, 0 ),
-    /*  FlipRgOFF */  PACK( 2, 0 ),
-    /*  INS_$83   */  PACK( 0, 0 ),
-    /*  INS_$84   */  PACK( 0, 0 ),
-    /*  ScanCTRL  */  PACK( 1, 0 ),
-    /*  SDPvTL[0] */  PACK( 2, 0 ),
-    /*  SDPvTL[1] */  PACK( 2, 0 ),
-    /*  GetINFO   */  PACK( 1, 1 ),
-    /*  IDEF      */  PACK( 1, 0 ),
-    /*  ROLL      */  PACK( 3, 3 ),
-    /*  MAX       */  PACK( 2, 1 ),
-    /*  MIN       */  PACK( 2, 1 ),
-    /*  ScanTYPE  */  PACK( 1, 0 ),
-    /*  InstCTRL  */  PACK( 2, 0 ),
-    /*  INS_$8F   */  PACK( 0, 0 ),
-
-    /*  INS_$90  */   PACK( 0, 0 ),
-    /*  INS_$91  */   PACK( 0, 0 ),
-    /*  INS_$92  */   PACK( 0, 0 ),
-    /*  INS_$93  */   PACK( 0, 0 ),
-    /*  INS_$94  */   PACK( 0, 0 ),
-    /*  INS_$95  */   PACK( 0, 0 ),
-    /*  INS_$96  */   PACK( 0, 0 ),
-    /*  INS_$97  */   PACK( 0, 0 ),
-    /*  INS_$98  */   PACK( 0, 0 ),
-    /*  INS_$99  */   PACK( 0, 0 ),
-    /*  INS_$9A  */   PACK( 0, 0 ),
-    /*  INS_$9B  */   PACK( 0, 0 ),
-    /*  INS_$9C  */   PACK( 0, 0 ),
-    /*  INS_$9D  */   PACK( 0, 0 ),
-    /*  INS_$9E  */   PACK( 0, 0 ),
-    /*  INS_$9F  */   PACK( 0, 0 ),
-
-    /*  INS_$A0  */   PACK( 0, 0 ),
-    /*  INS_$A1  */   PACK( 0, 0 ),
-    /*  INS_$A2  */   PACK( 0, 0 ),
-    /*  INS_$A3  */   PACK( 0, 0 ),
-    /*  INS_$A4  */   PACK( 0, 0 ),
-    /*  INS_$A5  */   PACK( 0, 0 ),
-    /*  INS_$A6  */   PACK( 0, 0 ),
-    /*  INS_$A7  */   PACK( 0, 0 ),
-    /*  INS_$A8  */   PACK( 0, 0 ),
-    /*  INS_$A9  */   PACK( 0, 0 ),
-    /*  INS_$AA  */   PACK( 0, 0 ),
-    /*  INS_$AB  */   PACK( 0, 0 ),
-    /*  INS_$AC  */   PACK( 0, 0 ),
-    /*  INS_$AD  */   PACK( 0, 0 ),
-    /*  INS_$AE  */   PACK( 0, 0 ),
-    /*  INS_$AF  */   PACK( 0, 0 ),
-
-    /*  PushB[0]  */  PACK( 0, 1 ),
-    /*  PushB[1]  */  PACK( 0, 2 ),
-    /*  PushB[2]  */  PACK( 0, 3 ),
-    /*  PushB[3]  */  PACK( 0, 4 ),
-    /*  PushB[4]  */  PACK( 0, 5 ),
-    /*  PushB[5]  */  PACK( 0, 6 ),
-    /*  PushB[6]  */  PACK( 0, 7 ),
-    /*  PushB[7]  */  PACK( 0, 8 ),
-    /*  PushW[0]  */  PACK( 0, 1 ),
-    /*  PushW[1]  */  PACK( 0, 2 ),
-    /*  PushW[2]  */  PACK( 0, 3 ),
-    /*  PushW[3]  */  PACK( 0, 4 ),
-    /*  PushW[4]  */  PACK( 0, 5 ),
-    /*  PushW[5]  */  PACK( 0, 6 ),
-    /*  PushW[6]  */  PACK( 0, 7 ),
-    /*  PushW[7]  */  PACK( 0, 8 ),
-
-    /*  MDRP[00]  */  PACK( 1, 0 ),
-    /*  MDRP[01]  */  PACK( 1, 0 ),
-    /*  MDRP[02]  */  PACK( 1, 0 ),
-    /*  MDRP[03]  */  PACK( 1, 0 ),
-    /*  MDRP[04]  */  PACK( 1, 0 ),
-    /*  MDRP[05]  */  PACK( 1, 0 ),
-    /*  MDRP[06]  */  PACK( 1, 0 ),
-    /*  MDRP[07]  */  PACK( 1, 0 ),
-    /*  MDRP[08]  */  PACK( 1, 0 ),
-    /*  MDRP[09]  */  PACK( 1, 0 ),
-    /*  MDRP[10]  */  PACK( 1, 0 ),
-    /*  MDRP[11]  */  PACK( 1, 0 ),
-    /*  MDRP[12]  */  PACK( 1, 0 ),
-    /*  MDRP[13]  */  PACK( 1, 0 ),
-    /*  MDRP[14]  */  PACK( 1, 0 ),
-    /*  MDRP[15]  */  PACK( 1, 0 ),
-
-    /*  MDRP[16]  */  PACK( 1, 0 ),
-    /*  MDRP[17]  */  PACK( 1, 0 ),
-    /*  MDRP[18]  */  PACK( 1, 0 ),
-    /*  MDRP[19]  */  PACK( 1, 0 ),
-    /*  MDRP[20]  */  PACK( 1, 0 ),
-    /*  MDRP[21]  */  PACK( 1, 0 ),
-    /*  MDRP[22]  */  PACK( 1, 0 ),
-    /*  MDRP[23]  */  PACK( 1, 0 ),
-    /*  MDRP[24]  */  PACK( 1, 0 ),
-    /*  MDRP[25]  */  PACK( 1, 0 ),
-    /*  MDRP[26]  */  PACK( 1, 0 ),
-    /*  MDRP[27]  */  PACK( 1, 0 ),
-    /*  MDRP[28]  */  PACK( 1, 0 ),
-    /*  MDRP[29]  */  PACK( 1, 0 ),
-    /*  MDRP[30]  */  PACK( 1, 0 ),
-    /*  MDRP[31]  */  PACK( 1, 0 ),
-
-    /*  MIRP[00]  */  PACK( 2, 0 ),
-    /*  MIRP[01]  */  PACK( 2, 0 ),
-    /*  MIRP[02]  */  PACK( 2, 0 ),
-    /*  MIRP[03]  */  PACK( 2, 0 ),
-    /*  MIRP[04]  */  PACK( 2, 0 ),
-    /*  MIRP[05]  */  PACK( 2, 0 ),
-    /*  MIRP[06]  */  PACK( 2, 0 ),
-    /*  MIRP[07]  */  PACK( 2, 0 ),
-    /*  MIRP[08]  */  PACK( 2, 0 ),
-    /*  MIRP[09]  */  PACK( 2, 0 ),
-    /*  MIRP[10]  */  PACK( 2, 0 ),
-    /*  MIRP[11]  */  PACK( 2, 0 ),
-    /*  MIRP[12]  */  PACK( 2, 0 ),
-    /*  MIRP[13]  */  PACK( 2, 0 ),
-    /*  MIRP[14]  */  PACK( 2, 0 ),
-    /*  MIRP[15]  */  PACK( 2, 0 ),
-
-    /*  MIRP[16]  */  PACK( 2, 0 ),
-    /*  MIRP[17]  */  PACK( 2, 0 ),
-    /*  MIRP[18]  */  PACK( 2, 0 ),
-    /*  MIRP[19]  */  PACK( 2, 0 ),
-    /*  MIRP[20]  */  PACK( 2, 0 ),
-    /*  MIRP[21]  */  PACK( 2, 0 ),
-    /*  MIRP[22]  */  PACK( 2, 0 ),
-    /*  MIRP[23]  */  PACK( 2, 0 ),
-    /*  MIRP[24]  */  PACK( 2, 0 ),
-    /*  MIRP[25]  */  PACK( 2, 0 ),
-    /*  MIRP[26]  */  PACK( 2, 0 ),
-    /*  MIRP[27]  */  PACK( 2, 0 ),
-    /*  MIRP[28]  */  PACK( 2, 0 ),
-    /*  MIRP[29]  */  PACK( 2, 0 ),
-    /*  MIRP[30]  */  PACK( 2, 0 ),
-    /*  MIRP[31]  */  PACK( 2, 0 )
-  };
-
-
-#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] =
-  {
-    "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 */
-
-
-  static
-  const FT_Char  opcode_length[256] =
-  {
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-
-   -1,-2, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,
-
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
-    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1
-  };
-
-#undef PACK
-
-
-#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
-
-#if defined( __arm__ )                                 && \
-    ( defined( __thumb2__ ) || !defined( __thumb__ ) )
-
-#define TT_MulFix14  TT_MulFix14_arm
-
-  static FT_Int32
-  TT_MulFix14_arm( FT_Int32  a,
-                   FT_Int    b )
-  {
-    FT_Int32  t, t2;
-
-
-#if defined( __CC_ARM ) || defined( __ARMCC__ )
-
-    __asm
-    {
-      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
-      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
-      add   a,  a,  #0x2000         /* a  += 0x2000 */
-      adds  t2, t2, a               /* t2 += a */
-      adc   t,  t,  #0              /* t  += carry */
-      mov   a,  t2, lsr #14         /* a   = t2 >> 14 */
-      orr   a,  a,  t,  lsl #18     /* a  |= t << 18 */
-    }
-
-#elif defined( __GNUC__ )
-
-    __asm__ __volatile__ (
-      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
-      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
-#if defined( __clang__ ) && defined( __thumb2__ )
-      "add.w  %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
-#else
-      "add    %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
-#endif
-      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
-      "adc    %2, %2, #0\n\t"           /* %2 += carry */
-      "mov    %0, %1, lsr #14\n\t"      /* %0  = %1 >> 16 */
-      "orr    %0, %0, %2, lsl #18\n\t"  /* %0 |= %2 << 16 */
-      : "=r"(a), "=&r"(t2), "=&r"(t)
-      : "r"(a), "r"(b)
-      : "cc" );
-
-#endif
-
-    return a;
-  }
-
-#endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */
-
-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
-
-
-#if defined( __GNUC__ )                              && \
-    ( defined( __i386__ ) || defined( __x86_64__ ) )
-
-#define TT_MulFix14  TT_MulFix14_long_long
-
-  /* Temporarily disable the warning that C90 doesn't support `long long'. */
-#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
-#pragma GCC diagnostic push
-#endif
-#pragma GCC diagnostic ignored "-Wlong-long"
-
-  /* This is declared `noinline' because inlining the function results */
-  /* in slower code.  The `pure' attribute indicates that the result   */
-  /* only depends on the parameters.                                   */
-  static __attribute__(( noinline ))
-         __attribute__(( pure )) FT_Int32
-  TT_MulFix14_long_long( FT_Int32  a,
-                         FT_Int    b )
-  {
-
-    long long  ret = (long long)a * b;
-
-    /* The following line assumes that right shifting of signed values */
-    /* will actually preserve the sign bit.  The exact behaviour is    */
-    /* undefined, but this is true on x86 and x86_64.                  */
-    long long  tmp = ret >> 63;
-
-
-    ret += 0x2000 + tmp;
-
-    return (FT_Int32)( ret >> 14 );
-  }
-
-#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
-#pragma GCC diagnostic pop
-#endif
-
-#endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */
-
-
-#ifndef TT_MulFix14
-
-  /* Compute (a*b)/2^14 with maximum accuracy and rounding.  */
-  /* This is optimized to be faster than calling FT_MulFix() */
-  /* for platforms where sizeof(int) == 2.                   */
-  static FT_Int32
-  TT_MulFix14( FT_Int32  a,
-               FT_Int    b )
-  {
-    FT_Int32   sign;
-    FT_UInt32  ah, al, mid, lo, hi;
-
-
-    sign = a ^ b;
-
-    if ( a < 0 )
-      a = -a;
-    if ( b < 0 )
-      b = -b;
-
-    ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
-    al = (FT_UInt32)( a & 0xFFFFU );
-
-    lo    = al * b;
-    mid   = ah * b;
-    hi    = mid >> 16;
-    mid   = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
-    lo   += mid;
-    if ( lo < mid )
-      hi += 1;
-
-    mid = ( lo >> 14 ) | ( hi << 18 );
-
-    return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
-  }
-
-#endif  /* !TT_MulFix14 */
-
-
-#if defined( __GNUC__ )        && \
-    ( defined( __i386__ )   ||    \
-      defined( __x86_64__ ) ||    \
-      defined( __arm__ )    )
-
-#define TT_DotFix14  TT_DotFix14_long_long
-
-#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
-#pragma GCC diagnostic push
-#endif
-#pragma GCC diagnostic ignored "-Wlong-long"
-
-  static __attribute__(( pure )) FT_Int32
-  TT_DotFix14_long_long( FT_Int32  ax,
-                         FT_Int32  ay,
-                         FT_Int    bx,
-                         FT_Int    by )
-  {
-    /* Temporarily disable the warning that C90 doesn't support */
-    /* `long long'.                                             */
-
-    long long  temp1 = (long long)ax * bx;
-    long long  temp2 = (long long)ay * by;
-
-
-    temp1 += temp2;
-    temp2  = temp1 >> 63;
-    temp1 += 0x2000 + temp2;
-
-    return (FT_Int32)( temp1 >> 14 );
-
-  }
-
-#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
-#pragma GCC diagnostic pop
-#endif
-
-#endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */
-
-
-#ifndef TT_DotFix14
-
-  /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */
-  static FT_Int32
-  TT_DotFix14( FT_Int32  ax,
-               FT_Int32  ay,
-               FT_Int    bx,
-               FT_Int    by )
-  {
-    FT_Int32   m, s, hi1, hi2, hi;
-    FT_UInt32  l, lo1, lo2, lo;
-
-
-    /* compute ax*bx as 64-bit value */
-    l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
-    m = ( ax >> 16 ) * bx;
-
-    lo1 = l + ( (FT_UInt32)m << 16 );
-    hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
-
-    /* compute ay*by as 64-bit value */
-    l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
-    m = ( ay >> 16 ) * by;
-
-    lo2 = l + ( (FT_UInt32)m << 16 );
-    hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
-
-    /* add them */
-    lo = lo1 + lo2;
-    hi = hi1 + hi2 + ( lo < lo1 );
-
-    /* divide the result by 2^14 with rounding */
-    s   = hi >> 31;
-    l   = lo + (FT_UInt32)s;
-    hi += s + ( l < lo );
-    lo  = l;
-
-    l   = lo + 0x2000U;
-    hi += ( l < lo );
-
-    return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
-  }
-
-#endif /* TT_DotFix14 */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Current_Ratio                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Returns the current aspect ratio scaling factor depending on the   */
-  /*    projection vector's state and device resolutions.                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
-  /*                                                                       */
-  static FT_Long
-  Current_Ratio( TT_ExecContext  exc )
-  {
-    if ( !exc->tt_metrics.ratio )
-    {
-      if ( exc->GS.projVector.y == 0 )
-        exc->tt_metrics.ratio = exc->tt_metrics.x_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( 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 exc->tt_metrics.ratio;
-  }
-
-
-  FT_CALLBACK_DEF( FT_Long )
-  Current_Ppem( TT_ExecContext  exc )
-  {
-    return exc->tt_metrics.ppem;
-  }
-
-
-  FT_CALLBACK_DEF( FT_Long )
-  Current_Ppem_Stretched( TT_ExecContext  exc )
-  {
-    return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Functions related to the control value table (CVT).                   */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  FT_CALLBACK_DEF( FT_F26Dot6 )
-  Read_CVT( TT_ExecContext  exc,
-            FT_ULong        idx )
-  {
-    return exc->cvt[idx];
-  }
-
-
-  FT_CALLBACK_DEF( FT_F26Dot6 )
-  Read_CVT_Stretched( TT_ExecContext  exc,
-                      FT_ULong        idx )
-  {
-    return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  Write_CVT( TT_ExecContext  exc,
-             FT_ULong        idx,
-             FT_F26Dot6      value )
-  {
-    exc->cvt[idx] = value;
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  Write_CVT_Stretched( TT_ExecContext  exc,
-                       FT_ULong        idx,
-                       FT_F26Dot6      value )
-  {
-    exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  Move_CVT( TT_ExecContext  exc,
-            FT_ULong        idx,
-            FT_F26Dot6      value )
-  {
-    exc->cvt[idx] += value;
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  Move_CVT_Stretched( TT_ExecContext  exc,
-                      FT_ULong        idx,
-                      FT_F26Dot6      value )
-  {
-    exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    GetShortIns                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Returns a short integer taken from the instruction stream at       */
-  /*    address IP.                                                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Short read at code[IP].                                            */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This one could become a macro.                                     */
-  /*                                                                       */
-  static FT_Short
-  GetShortIns( TT_ExecContext  exc )
-  {
-    /* Reading a byte stream so there is no endianess (DaveP) */
-    exc->IP += 2;
-    return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
-                         exc->code[exc->IP - 1]      );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Ins_Goto_CodeRange                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Goes to a certain code range in the instruction stream.            */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    aRange :: The index of the code range.                             */
-  /*                                                                       */
-  /*    aIP    :: The new IP address in the code range.                    */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static FT_Bool
-  Ins_Goto_CodeRange( TT_ExecContext  exc,
-                      FT_Int          aRange,
-                      FT_Long         aIP )
-  {
-    TT_CodeRange*  range;
-
-
-    if ( aRange < 1 || aRange > 3 )
-    {
-      exc->error = FT_THROW( Bad_Argument );
-      return FAILURE;
-    }
-
-    range = &exc->codeRangeTable[aRange - 1];
-
-    if ( range->base == NULL )     /* invalid coderange */
-    {
-      exc->error = FT_THROW( Invalid_CodeRange );
-      return FAILURE;
-    }
-
-    /* NOTE: Because the last instruction of a program may be a CALL */
-    /*       which will return to the first byte *after* the code    */
-    /*       range, we test for aIP <= Size, instead of aIP < Size.  */
-
-    if ( aIP > range->size )
-    {
-      exc->error = FT_THROW( Code_Overflow );
-      return FAILURE;
-    }
-
-    exc->code     = range->base;
-    exc->codeSize = range->size;
-    exc->IP       = aIP;
-    exc->curRange = aRange;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Direct_Move                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Moves a point by a given distance along the freedom vector.  The   */
-  /*    point will be `touched'.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    point    :: The index of the point to move.                        */
-  /*                                                                       */
-  /*    distance :: The distance to apply.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    zone     :: The affected glyph zone.                               */
-  /*                                                                       */
-  static void
-  Direct_Move( TT_ExecContext  exc,
-               TT_GlyphZone    zone,
-               FT_UShort       point,
-               FT_F26Dot6      distance )
-  {
-    FT_F26Dot6  v;
-
-
-    v = exc->GS.freeVector.x;
-
-    if ( v != 0 )
-    {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      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, exc->F_dot_P );
-
-      zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
-    }
-
-    v = exc->GS.freeVector.y;
-
-    if ( v != 0 )
-    {
-      zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
-
-      zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Direct_Move_Orig                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Moves the *original* position of a point by a given distance along */
-  /*    the freedom vector.  Obviously, the point will not be `touched'.   */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    point    :: The index of the point to move.                        */
-  /*                                                                       */
-  /*    distance :: The distance to apply.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    zone     :: The affected glyph zone.                               */
-  /*                                                                       */
-  static void
-  Direct_Move_Orig( TT_ExecContext  exc,
-                    TT_GlyphZone    zone,
-                    FT_UShort       point,
-                    FT_F26Dot6      distance )
-  {
-    FT_F26Dot6  v;
-
-
-    v = exc->GS.freeVector.x;
-
-    if ( v != 0 )
-      zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
-
-    v = exc->GS.freeVector.y;
-
-    if ( v != 0 )
-      zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Special versions of Direct_Move()                                     */
-  /*                                                                       */
-  /*   The following versions are used whenever both vectors are both      */
-  /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  static void
-  Direct_Move_X( TT_ExecContext  exc,
-                 TT_GlyphZone    zone,
-                 FT_UShort       point,
-                 FT_F26Dot6      distance )
-  {
-    FT_UNUSED( exc );
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( !SUBPIXEL_HINTING   ||
-         !exc->ignore_x_mode )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-      zone->cur[point].x += distance;
-
-    zone->tags[point]  |= FT_CURVE_TAG_TOUCH_X;
-  }
-
-
-  static void
-  Direct_Move_Y( TT_ExecContext  exc,
-                 TT_GlyphZone    zone,
-                 FT_UShort       point,
-                 FT_F26Dot6      distance )
-  {
-    FT_UNUSED( exc );
-
-    zone->cur[point].y += distance;
-    zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Special versions of Direct_Move_Orig()                                */
-  /*                                                                       */
-  /*   The following versions are used whenever both vectors are both      */
-  /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  static void
-  Direct_Move_Orig_X( TT_ExecContext  exc,
-                      TT_GlyphZone    zone,
-                      FT_UShort       point,
-                      FT_F26Dot6      distance )
-  {
-    FT_UNUSED( exc );
-
-    zone->org[point].x += distance;
-  }
-
-
-  static void
-  Direct_Move_Orig_Y( TT_ExecContext  exc,
-                      TT_GlyphZone    zone,
-                      FT_UShort       point,
-                      FT_F26Dot6      distance )
-  {
-    FT_UNUSED( exc );
-
-    zone->org[point].y += distance;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_None                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Does not round, but adds engine compensation.                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance (not) to round.                       */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The compensated distance.                                          */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The TrueType specification says very few about the relationship    */
-  /*    between rounding and engine compensation.  However, it seems from  */
-  /*    the description of super round that we should add the compensation */
-  /*    before rounding.                                                   */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_None( TT_ExecContext  exc,
-              FT_F26Dot6      distance,
-              FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = distance + compensation;
-      if ( val < 0 )
-        val = 0;
-    }
-    else
-    {
-      val = distance - compensation;
-      if ( val > 0 )
-        val = 0;
-    }
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_To_Grid                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Rounds value to grid after adding engine compensation.             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_To_Grid( TT_ExecContext  exc,
-                 FT_F26Dot6      distance,
-                 FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = FT_PIX_ROUND( distance + compensation );
-      if ( val < 0 )
-        val = 0;
-    }
-    else
-    {
-      val = -FT_PIX_ROUND( compensation - distance );
-      if ( val > 0 )
-        val = 0;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_To_Half_Grid                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Rounds value to half grid after adding engine compensation.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_To_Half_Grid( TT_ExecContext  exc,
-                      FT_F26Dot6      distance,
-                      FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = FT_PIX_FLOOR( distance + compensation ) + 32;
-      if ( val < 0 )
-        val = 32;
-    }
-    else
-    {
-      val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
-      if ( val > 0 )
-        val = -32;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_Down_To_Grid                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Rounds value down to grid after adding engine compensation.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_Down_To_Grid( TT_ExecContext  exc,
-                      FT_F26Dot6      distance,
-                      FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = FT_PIX_FLOOR( distance + compensation );
-      if ( val < 0 )
-        val = 0;
-    }
-    else
-    {
-      val = -FT_PIX_FLOOR( compensation - distance );
-      if ( val > 0 )
-        val = 0;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_Up_To_Grid                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Rounds value up to grid after adding engine compensation.          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_Up_To_Grid( TT_ExecContext  exc,
-                    FT_F26Dot6      distance,
-                    FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = FT_PIX_CEIL( distance + compensation );
-      if ( val < 0 )
-        val = 0;
-    }
-    else
-    {
-      val = -FT_PIX_CEIL( compensation - distance );
-      if ( val > 0 )
-        val = 0;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_To_Double_Grid                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Rounds value to double grid after adding engine compensation.      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_To_Double_Grid( TT_ExecContext  exc,
-                        FT_F26Dot6      distance,
-                        FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6 val;
-
-    FT_UNUSED( exc );
-
-
-    if ( distance >= 0 )
-    {
-      val = FT_PAD_ROUND( distance + compensation, 32 );
-      if ( val < 0 )
-        val = 0;
-    }
-    else
-    {
-      val = -FT_PAD_ROUND( compensation - distance, 32 );
-      if ( val > 0 )
-        val = 0;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_Super                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Super-rounds value to grid after adding engine compensation.       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The TrueType specification says very few about the relationship    */
-  /*    between rounding and engine compensation.  However, it seems from  */
-  /*    the description of super round that we should add the compensation */
-  /*    before rounding.                                                   */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_Super( TT_ExecContext  exc,
-               FT_F26Dot6      distance,
-               FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-
-    if ( distance >= 0 )
-    {
-      val = ( distance - exc->phase + exc->threshold + compensation ) &
-              -exc->period;
-      val += exc->phase;
-      if ( val < 0 )
-        val = exc->phase;
-    }
-    else
-    {
-      val = -( ( exc->threshold - exc->phase - distance + compensation ) &
-               -exc->period );
-      val -= exc->phase;
-      if ( val > 0 )
-        val = -exc->phase;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Round_Super_45                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Super-rounds value to grid after adding engine compensation.       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    distance     :: The distance to round.                             */
-  /*                                                                       */
-  /*    compensation :: The engine compensation.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Rounded distance.                                                  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    There is a separate function for Round_Super_45() as we may need   */
-  /*    greater precision.                                                 */
-  /*                                                                       */
-  static FT_F26Dot6
-  Round_Super_45( TT_ExecContext  exc,
-                  FT_F26Dot6      distance,
-                  FT_F26Dot6      compensation )
-  {
-    FT_F26Dot6  val;
-
-
-    if ( distance >= 0 )
-    {
-      val = ( ( distance - exc->phase + exc->threshold + compensation ) /
-                exc->period ) * exc->period;
-      val += exc->phase;
-      if ( val < 0 )
-        val = exc->phase;
-    }
-    else
-    {
-      val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
-                   exc->period ) * exc->period );
-      val -= exc->phase;
-      if ( val > 0 )
-        val = -exc->phase;
-    }
-
-    return val;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Compute_Round                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets the rounding mode.                                            */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    round_mode :: The rounding mode to be used.                        */
-  /*                                                                       */
-  static void
-  Compute_Round( TT_ExecContext  exc,
-                 FT_Byte         round_mode )
-  {
-    switch ( round_mode )
-    {
-    case TT_Round_Off:
-      exc->func_round = (TT_Round_Func)Round_None;
-      break;
-
-    case TT_Round_To_Grid:
-      exc->func_round = (TT_Round_Func)Round_To_Grid;
-      break;
-
-    case TT_Round_Up_To_Grid:
-      exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
-      break;
-
-    case TT_Round_Down_To_Grid:
-      exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
-      break;
-
-    case TT_Round_To_Half_Grid:
-      exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
-      break;
-
-    case TT_Round_To_Double_Grid:
-      exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
-      break;
-
-    case TT_Round_Super:
-      exc->func_round = (TT_Round_Func)Round_Super;
-      break;
-
-    case TT_Round_Super_45:
-      exc->func_round = (TT_Round_Func)Round_Super_45;
-      break;
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    SetSuperRound                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets Super Round parameters.                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    GridPeriod :: The grid period.                                     */
-  /*                                                                       */
-  /*    selector   :: The SROUND opcode.                                   */
-  /*                                                                       */
-  static void
-  SetSuperRound( TT_ExecContext  exc,
-                 FT_F2Dot14      GridPeriod,
-                 FT_Long         selector )
-  {
-    switch ( (FT_Int)( selector & 0xC0 ) )
-    {
-      case 0:
-        exc->period = GridPeriod / 2;
-        break;
-
-      case 0x40:
-        exc->period = GridPeriod;
-        break;
-
-      case 0x80:
-        exc->period = GridPeriod * 2;
-        break;
-
-      /* This opcode is reserved, but... */
-      case 0xC0:
-        exc->period = GridPeriod;
-        break;
-    }
-
-    switch ( (FT_Int)( selector & 0x30 ) )
-    {
-    case 0:
-      exc->phase = 0;
-      break;
-
-    case 0x10:
-      exc->phase = exc->period / 4;
-      break;
-
-    case 0x20:
-      exc->phase = exc->period / 2;
-      break;
-
-    case 0x30:
-      exc->phase = exc->period * 3 / 4;
-      break;
-    }
-
-    if ( ( selector & 0x0F ) == 0 )
-      exc->threshold = exc->period - 1;
-    else
-      exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
-
-    /* convert to F26Dot6 format */
-    exc->period    >>= 8;
-    exc->phase     >>= 8;
-    exc->threshold >>= 8;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Project                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the projection of vector given by (v2-v1) along the       */
-  /*    current projection vector.                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    v1 :: First input vector.                                          */
-  /*    v2 :: Second input vector.                                         */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The distance in F26dot6 format.                                    */
-  /*                                                                       */
-  static FT_F26Dot6
-  Project( TT_ExecContext  exc,
-           FT_Pos          dx,
-           FT_Pos          dy )
-  {
-    return TT_DotFix14( dx, dy,
-                        exc->GS.projVector.x,
-                        exc->GS.projVector.y );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Dual_Project                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the projection of the vector given by (v2-v1) along the   */
-  /*    current dual vector.                                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    v1 :: First input vector.                                          */
-  /*    v2 :: Second input vector.                                         */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The distance in F26dot6 format.                                    */
-  /*                                                                       */
-  static FT_F26Dot6
-  Dual_Project( TT_ExecContext  exc,
-                FT_Pos          dx,
-                FT_Pos          dy )
-  {
-    return TT_DotFix14( dx, dy,
-                        exc->GS.dualVector.x,
-                        exc->GS.dualVector.y );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Project_x                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the projection of the vector given by (v2-v1) along the   */
-  /*    horizontal axis.                                                   */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    v1 :: First input vector.                                          */
-  /*    v2 :: Second input vector.                                         */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The distance in F26dot6 format.                                    */
-  /*                                                                       */
-  static FT_F26Dot6
-  Project_x( TT_ExecContext  exc,
-             FT_Pos          dx,
-             FT_Pos          dy )
-  {
-    FT_UNUSED( exc );
-    FT_UNUSED( dy );
-
-    return dx;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Project_y                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the projection of the vector given by (v2-v1) along the   */
-  /*    vertical axis.                                                     */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    v1 :: First input vector.                                          */
-  /*    v2 :: Second input vector.                                         */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The distance in F26dot6 format.                                    */
-  /*                                                                       */
-  static FT_F26Dot6
-  Project_y( TT_ExecContext  exc,
-             FT_Pos          dx,
-             FT_Pos          dy )
-  {
-    FT_UNUSED( exc );
-    FT_UNUSED( dx );
-
-    return dy;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Compute_Funcs                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the projection and movement function pointers according   */
-  /*    to the current graphics state.                                     */
-  /*                                                                       */
-  static void
-  Compute_Funcs( TT_ExecContext  exc )
-  {
-    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
-      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
-      exc->func_project = (TT_Project_Func)Project;
-
-    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
-      exc->func_dualproj = (TT_Project_Func)Dual_Project;
-
-    exc->func_move      = (TT_Move_Func)Direct_Move;
-    exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
-
-    if ( exc->F_dot_P == 0x4000L )
-    {
-      if ( exc->GS.freeVector.x == 0x4000 )
-      {
-        exc->func_move      = (TT_Move_Func)Direct_Move_X;
-        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
-      }
-      else if ( exc->GS.freeVector.y == 0x4000 )
-      {
-        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( exc->F_dot_P ) < 0x400L )
-      exc->F_dot_P = 0x4000L;
-
-    /* Disable cached aspect ratio */
-    exc->tt_metrics.ratio = 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Normalize                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Norms a vector.                                                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    Vx :: The horizontal input vector coordinate.                      */
-  /*    Vy :: The vertical input vector coordinate.                        */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    R  :: The normed unit vector.                                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Returns FAILURE if a vector parameter is zero.                     */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and  */
-  /*    R is undefined.                                                    */
-  /*                                                                       */
-  static FT_Bool
-  Normalize( FT_F26Dot6      Vx,
-             FT_F26Dot6      Vy,
-             FT_UnitVector*  R )
-  {
-    FT_Vector V;
-
-
-    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;
-    }
-
-    V.x = Vx;
-    V.y = Vy;
-
-    FT_Vector_NormLen( &V );
-
-    R->x = (FT_F2Dot14)( V.x / 4 );
-    R->y = (FT_F2Dot14)( V.y / 4 );
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Here we start with the implementation of the various opcodes.         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define ARRAY_BOUND_ERROR                         \
-    do                                            \
-    {                                             \
-      exc->error = FT_THROW( Invalid_Reference ); \
-      return;                                     \
-    } while (0)
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* POP[]:        POP the stack's top element                             */
-  /* Opcode range: 0x21                                                    */
-  /* Stack:        StkElt -->                                              */
-  /*                                                                       */
-  static void
-  Ins_POP( void )
-  {
-    /* nothing to do */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CLEAR[]:      CLEAR the entire stack                                  */
-  /* Opcode range: 0x22                                                    */
-  /* Stack:        StkElt... -->                                           */
-  /*                                                                       */
-  static void
-  Ins_CLEAR( TT_ExecContext  exc )
-  {
-    exc->new_top = 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-
-
-    L       = args[0];
-    args[0] = args[1];
-    args[1] = L;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DEPTH[]:      return the stack DEPTH                                  */
-  /* Opcode range: 0x24                                                    */
-  /* Stack:        --> uint32                                              */
-  /*                                                                       */
-  static void
-  Ins_DEPTH( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    args[0] = exc->top;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* LT[]:         Less Than                                               */
-  /* Opcode range: 0x50                                                    */
-  /* Stack:        int32? int32? --> bool                                  */
-  /*                                                                       */
-  static void
-  Ins_LT( FT_Long*  args )
-  {
-    args[0] = ( args[0] < args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GT[]:         Greater Than                                            */
-  /* Opcode range: 0x52                                                    */
-  /* Stack:        int32? int32? --> bool                                  */
-  /*                                                                       */
-  static void
-  Ins_GT( FT_Long*  args )
-  {
-    args[0] = ( args[0] > args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* EQ[]:         EQual                                                   */
-  /* Opcode range: 0x54                                                    */
-  /* Stack:        StkElt StkElt --> bool                                  */
-  /*                                                                       */
-  static void
-  Ins_EQ( FT_Long*  args )
-  {
-    args[0] = ( args[0] == args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NEQ[]:        Not EQual                                               */
-  /* Opcode range: 0x55                                                    */
-  /* Stack:        StkElt StkElt --> bool                                  */
-  /*                                                                       */
-  static void
-  Ins_NEQ( FT_Long*  args )
-  {
-    args[0] = ( args[0] != args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ODD[]:        Is ODD                                                  */
-  /* Opcode range: 0x56                                                    */
-  /* Stack:        f26.6 --> bool                                          */
-  /*                                                                       */
-  static void
-  Ins_ODD( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* EVEN[]:       Is EVEN                                                 */
-  /* Opcode range: 0x57                                                    */
-  /* Stack:        f26.6 --> bool                                          */
-  /*                                                                       */
-  static void
-  Ins_EVEN( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* AND[]:        logical AND                                             */
-  /* Opcode range: 0x5A                                                    */
-  /* Stack:        uint32 uint32 --> uint32                                */
-  /*                                                                       */
-  static void
-  Ins_AND( FT_Long*  args )
-  {
-    args[0] = ( args[0] && args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* OR[]:         logical OR                                              */
-  /* Opcode range: 0x5B                                                    */
-  /* Stack:        uint32 uint32 --> uint32                                */
-  /*                                                                       */
-  static void
-  Ins_OR( FT_Long*  args )
-  {
-    args[0] = ( args[0] || args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NOT[]:        logical NOT                                             */
-  /* Opcode range: 0x5C                                                    */
-  /* Stack:        StkElt --> uint32                                       */
-  /*                                                                       */
-  static void
-  Ins_NOT( FT_Long*  args )
-  {
-    args[0] = !args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ADD[]:        ADD                                                     */
-  /* Opcode range: 0x60                                                    */
-  /* Stack:        f26.6 f26.6 --> f26.6                                   */
-  /*                                                                       */
-  static void
-  Ins_ADD( FT_Long*  args )
-  {
-    args[0] += args[1];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SUB[]:        SUBtract                                                */
-  /* Opcode range: 0x61                                                    */
-  /* Stack:        f26.6 f26.6 --> f26.6                                   */
-  /*                                                                       */
-  static void
-  Ins_SUB( FT_Long*  args )
-  {
-    args[0] -= args[1];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DIV[]:        DIVide                                                  */
-  /* Opcode range: 0x62                                                    */
-  /* Stack:        f26.6 f26.6 --> f26.6                                   */
-  /*                                                                       */
-  static void
-  Ins_DIV( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    if ( args[1] == 0 )
-      exc->error = FT_THROW( Divide_By_Zero );
-    else
-      args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MUL[]:        MULtiply                                                */
-  /* Opcode range: 0x63                                                    */
-  /* Stack:        f26.6 f26.6 --> f26.6                                   */
-  /*                                                                       */
-  static void
-  Ins_MUL( FT_Long*  args )
-  {
-    args[0] = FT_MulDiv( args[0], args[1], 64L );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ABS[]:        ABSolute value                                          */
-  /* Opcode range: 0x64                                                    */
-  /* Stack:        f26.6 --> f26.6                                         */
-  /*                                                                       */
-  static void
-  Ins_ABS( FT_Long*  args )
-  {
-    args[0] = FT_ABS( args[0] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NEG[]:        NEGate                                                  */
-  /* Opcode range: 0x65                                                    */
-  /* Stack: f26.6 --> f26.6                                                */
-  /*                                                                       */
-  static void
-  Ins_NEG( FT_Long*  args )
-  {
-    args[0] = -args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLOOR[]:      FLOOR                                                   */
-  /* Opcode range: 0x66                                                    */
-  /* Stack:        f26.6 --> f26.6                                         */
-  /*                                                                       */
-  static void
-  Ins_FLOOR( FT_Long*  args )
-  {
-    args[0] = FT_PIX_FLOOR( args[0] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CEILING[]:    CEILING                                                 */
-  /* Opcode range: 0x67                                                    */
-  /* Stack:        f26.6 --> f26.6                                         */
-  /*                                                                       */
-  static void
-  Ins_CEILING( FT_Long*  args )
-  {
-    args[0] = FT_PIX_CEIL( args[0] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RS[]:         Read Store                                              */
-  /* Opcode range: 0x43                                                    */
-  /* Stack:        uint32 --> uint32                                       */
-  /*                                                                       */
-  static void
-  Ins_RS( TT_ExecContext  exc,
-          FT_Long*        args )
-  {
-#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 */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* WS[]:         Write Store                                             */
-  /* Opcode range: 0x42                                                    */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_WS( TT_ExecContext  exc,
-          FT_Long*        args )
-  {
-    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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* WCVTP[]:      Write CVT in Pixel units                                */
-  /* Opcode range: 0x44                                                    */
-  /* Stack:        f26.6 uint32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_WCVTP( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    FT_ULong  I = (FT_ULong)args[0];
-
-
-    if ( BOUNDSL( I, exc->cvtSize ) )
-    {
-      if ( exc->pedantic_hinting )
-        ARRAY_BOUND_ERROR;
-    }
-    else
-      exc->func_write_cvt( exc, I, args[1] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* WCVTF[]:      Write CVT in Funits                                     */
-  /* Opcode range: 0x70                                                    */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_WCVTF( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RCVT[]:       Read CVT                                                */
-  /* Opcode range: 0x45                                                    */
-  /* Stack:        uint32 --> f26.6                                        */
-  /*                                                                       */
-  static void
-  Ins_RCVT( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* AA[]:         Adjust Angle                                            */
-  /* Opcode range: 0x7F                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_AA( void )
-  {
-    /* intentionally no longer supported */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DEBUG[]:      DEBUG.  Unsupported.                                    */
-  /* Opcode range: 0x4F                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  /* Note: The original instruction pops a value from the stack.           */
-  /*                                                                       */
-  static void
-  Ins_DEBUG( TT_ExecContext  exc )
-  {
-    exc->error = FT_THROW( Debug_OpCode );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ROUND[ab]:    ROUND value                                             */
-  /* Opcode range: 0x68-0x6B                                               */
-  /* Stack:        f26.6 --> f26.6                                         */
-  /*                                                                       */
-  static void
-  Ins_ROUND( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    args[0] = exc->func_round(
-                exc,
-                args[0],
-                exc->tt_metrics.compensations[exc->opcode - 0x68] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NROUND[ab]:   No ROUNDing of value                                    */
-  /* Opcode range: 0x6C-0x6F                                               */
-  /* Stack:        f26.6 --> f26.6                                         */
-  /*                                                                       */
-  static void
-  Ins_NROUND( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    args[0] = Round_None(
-                exc,
-                args[0],
-                exc->tt_metrics.compensations[exc->opcode - 0x6C] );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MAX[]:        MAXimum                                                 */
-  /* Opcode range: 0x68                                                    */
-  /* Stack:        int32? int32? --> int32                                 */
-  /*                                                                       */
-  static void
-  Ins_MAX( FT_Long*  args )
-  {
-    if ( args[1] > args[0] )
-      args[0] = args[1];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MIN[]:        MINimum                                                 */
-  /* Opcode range: 0x69                                                    */
-  /* Stack:        int32? int32? --> int32                                 */
-  /*                                                                       */
-  static void
-  Ins_MIN( FT_Long*  args )
-  {
-    if ( args[1] < args[0] )
-      args[0] = args[1];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MINDEX[]:     Move INDEXed element                                    */
-  /* Opcode range: 0x26                                                    */
-  /* Stack:        int32? --> StkElt                                       */
-  /*                                                                       */
-  static void
-  Ins_MINDEX( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    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;
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CINDEX[]:     Copy INDEXed element                                    */
-  /* Opcode range: 0x25                                                    */
-  /* Stack:        int32 --> StkElt                                        */
-  /*                                                                       */
-  static void
-  Ins_CINDEX( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ROLL[]:       ROLL top three elements                                 */
-  /* Opcode range: 0x8A                                                    */
-  /* Stack:        3 * StkElt --> 3 * StkElt                               */
-  /*                                                                       */
-  static void
-  Ins_ROLL( FT_Long*  args )
-  {
-    FT_Long  A, B, C;
-
-
-    A = args[2];
-    B = args[1];
-    C = args[0];
-
-    args[2] = C;
-    args[1] = A;
-    args[0] = B;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MANAGING THE FLOW OF CONTROL                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SLOOP[]:      Set LOOP variable                                       */
-  /* Opcode range: 0x17                                                    */
-  /* Stack:        int32? -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SLOOP( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    if ( args[0] < 0 )
-      exc->error = FT_THROW( Bad_Argument );
-    else
-      exc->GS.loop = args[0];
-  }
-
-
-  static FT_Bool
-  SkipCode( TT_ExecContext  exc )
-  {
-    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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* IF[]:         IF test                                                 */
-  /* Opcode range: 0x58                                                    */
-  /* Stack:        StkElt -->                                              */
-  /*                                                                       */
-  static void
-  Ins_IF( TT_ExecContext  exc,
-          FT_Long*        args )
-  {
-    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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ELSE[]:       ELSE                                                    */
-  /* Opcode range: 0x1B                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_ELSE( TT_ExecContext  exc )
-  {
-    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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* EIF[]:        End IF                                                  */
-  /* Opcode range: 0x59                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_EIF( void )
-  {
-    /* nothing to do */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JMPR[]:       JuMP Relative                                           */
-  /* Opcode range: 0x1C                                                    */
-  /* Stack:        int32 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_JMPR( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JROT[]:       Jump Relative On True                                   */
-  /* Opcode range: 0x78                                                    */
-  /* Stack:        StkElt int32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_JROT( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    if ( args[1] != 0 )
-      Ins_JMPR( exc, args );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JROF[]:       Jump Relative On False                                  */
-  /* Opcode range: 0x79                                                    */
-  /* Stack:        StkElt int32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_JROF( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    if ( args[1] == 0 )
-      Ins_JMPR( exc, args );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FDEF[]:       Function DEFinition                                     */
-  /* Opcode range: 0x2C                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_FDEF( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    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 */
-
-
-    /* some font programs are broken enough to redefine functions! */
-    /* We will then parse the current table.                       */
-
-    rec   = exc->FDefs;
-    limit = rec + exc->numFDefs;
-    n     = (FT_ULong)args[0];
-
-    for ( ; rec < limit; rec++ )
-    {
-      if ( rec->opc == n )
-        break;
-    }
-
-    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;
-    }
-
-    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;
-
-#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.    */
-
-    while ( SkipCode( exc ) == SUCCESS )
-    {
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-      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 ));
-
-              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;
-
-              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;
-
-              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;
-
-              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;
-
-              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;
-
-               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;
-            }
-          }
-
-          else
-            opcode_pointer[i] = 0;
-        }
-
-        /* 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 */
-
-      switch ( exc->opcode )
-      {
-      case 0x89:    /* IDEF */
-      case 0x2C:    /* FDEF */
-        exc->error = FT_THROW( Nested_DEFS );
-        return;
-
-      case 0x2D:   /* ENDF */
-        rec->end = exc->IP;
-        return;
-      }
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ENDF[]:       END Function definition                                 */
-  /* Opcode range: 0x2D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_ENDF( TT_ExecContext  exc )
-  {
-    TT_CallRec*  pRec;
-
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    exc->sph_in_func_flags = 0x0000;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
-    {
-      exc->error = FT_THROW( ENDF_In_Exec_Stream );
-      return;
-    }
-
-    exc->callTop--;
-
-    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 );
-
-    /* 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!    */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CALL[]:       CALL function                                           */
-  /* Opcode range: 0x2B                                                    */
-  /* Stack:        uint32? -->                                             */
-  /*                                                                       */
-  static void
-  Ins_CALL( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_ULong       F;
-    TT_CallRec*    pCrec;
-    TT_DefRecord*  def;
-
-
-    /* first of all, check the index */
-
-    F = (FT_ULong)args[0];
-    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;
-
-
-      def   = exc->FDefs;
-      limit = def + exc->numFDefs;
-
-      while ( def < limit && def->opc != F )
-        def++;
-
-      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                                             &&
-         ( ( 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;
-    }
-
-    pCrec = exc->callStack + exc->callTop;
-
-    pCrec->Caller_Range = exc->curRange;
-    pCrec->Caller_IP    = exc->IP + 1;
-    pCrec->Cur_Count    = 1;
-    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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* LOOPCALL[]:   LOOP and CALL function                                  */
-  /* Opcode range: 0x2A                                                    */
-  /* Stack:        uint32? Eint16? -->                                     */
-  /*                                                                       */
-  static void
-  Ins_LOOPCALL( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    FT_ULong       F;
-    TT_CallRec*    pCrec;
-    TT_DefRecord*  def;
-
-
-    /* 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;
-
-
-      def   = exc->FDefs;
-      limit = def + exc->numFDefs;
-
-      while ( def < limit && def->opc != F )
-        def++;
-
-      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 )
-    {
-      exc->error = FT_THROW( Stack_Overflow );
-      return;
-    }
-
-    if ( args[0] > 0 )
-    {
-      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 )
-      {
-        exc->error = FT_THROW( Too_Many_Instruction_Defs );
-        return;
-      }
-      exc->numIDefs++;
-    }
-
-    /* opcode must be unsigned 8-bit integer */
-    if ( 0 > args[0] || args[0] > 0x00FF )
-    {
-      exc->error = FT_THROW( Too_Many_Instruction_Defs );
-      return;
-    }
-
-    def->opc    = (FT_Byte)args[0];
-    def->start  = exc->IP + 1;
-    def->range  = exc->curRange;
-    def->active = TRUE;
-
-    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.    */
-
-    while ( SkipCode( exc ) == SUCCESS )
-    {
-      switch ( exc->opcode )
-      {
-      case 0x89:   /* IDEF */
-      case 0x2C:   /* FDEF */
-        exc->error = FT_THROW( Nested_DEFS );
-        return;
-      case 0x2D:   /* ENDF */
-        return;
-      }
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* PUSHING DATA ONTO THE INTERPRETER STACK                               */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NPUSHB[]:     PUSH N Bytes                                            */
-  /* Opcode range: 0x40                                                    */
-  /* Stack:        --> uint32...                                           */
-  /*                                                                       */
-  static void
-  Ins_NPUSHB( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    FT_UShort  L, K;
-
-
-    L = (FT_UShort)exc->code[exc->IP + 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 + 1];
-
-    exc->new_top += L;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* NPUSHW[]:     PUSH N Words                                            */
-  /* Opcode range: 0x41                                                    */
-  /* Stack:        --> int32...                                            */
-  /*                                                                       */
-  static void
-  Ins_NPUSHW( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    FT_UShort  L, K;
-
-
-    L = (FT_UShort)exc->code[exc->IP + 1];
-
-    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
-    {
-      exc->error = FT_THROW( Stack_Overflow );
-      return;
-    }
-
-    exc->IP += 2;
-
-    for ( K = 0; K < L; K++ )
-      args[K] = GetShortIns( exc );
-
-    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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* PUSHW[abc]:   PUSH Words                                              */
-  /* Opcode range: 0xB8-0xBF                                               */
-  /* Stack:        --> int32...                                            */
-  /*                                                                       */
-  static void
-  Ins_PUSHW( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    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                                           */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  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;
-
-
-    if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
-         BOUNDS( aIdx2, exc->zp1.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return FAILURE;
-    }
-
-    p1 = exc->zp1.cur + aIdx2;
-    p2 = exc->zp2.cur + aIdx1;
-
-    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.                    */
-
-    if ( A == 0 && B == 0 )
-    {
-      A      = 0x4000;
-      opcode = 0;
-    }
-
-    if ( ( opcode & 1 ) != 0 )
-    {
-      C =  B;   /* counter clockwise rotation */
-      B =  A;
-      A = -C;
-    }
-
-    Normalize( A, B, Vec );
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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_SxyTCA( TT_ExecContext  exc )
-  {
-    FT_Short  AA, BB;
-
-    FT_Byte  opcode = exc->opcode;
-
-
-    AA = (FT_Short)( ( opcode & 1 ) << 14 );
-    BB = (FT_Short)( AA ^ 0x4000 );
-
-    if ( opcode < 4 )
-    {
-      exc->GS.projVector.x = AA;
-      exc->GS.projVector.y = BB;
-
-      exc->GS.dualVector.x = AA;
-      exc->GS.dualVector.y = BB;
-    }
-
-    if ( ( opcode & 2 ) == 0 )
-    {
-      exc->GS.freeVector.x = AA;
-      exc->GS.freeVector.y = BB;
-    }
-
-    Compute_Funcs( exc );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-      Compute_Funcs( exc );
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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 )
-    {
-      Compute_Funcs( exc );
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SFvTPv[]:     Set FVector To PVector                                  */
-  /* Opcode range: 0x0E                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_SFVTPV( TT_ExecContext  exc )
-  {
-    exc->GS.freeVector = exc->GS.projVector;
-    Compute_Funcs( exc );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SPvFS[]:      Set PVector From Stack                                  */
-  /* Opcode range: 0x0A                                                    */
-  /* Stack:        f2.14 f2.14 -->                                         */
-  /*                                                                       */
-  static void
-  Ins_SPVFS( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    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, &exc->GS.projVector );
-
-    exc->GS.dualVector = exc->GS.projVector;
-    Compute_Funcs( exc );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-
-
-    /* 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, &exc->GS.freeVector );
-    Compute_Funcs( exc );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GPv[]:        Get Projection Vector                                   */
-  /* Opcode range: 0x0C                                                    */
-  /* Stack:        ef2.14 --> ef2.14                                       */
-  /*                                                                       */
-  static void
-  Ins_GPV( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    args[0] = exc->GS.projVector.x;
-    args[1] = exc->GS.projVector.y;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GFv[]:        Get Freedom Vector                                      */
-  /* Opcode range: 0x0D                                                    */
-  /* Stack:        ef2.14 --> ef2.14                                       */
-  /*                                                                       */
-  static void
-  Ins_GFV( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    args[0] = exc->GS.freeVector.x;
-    args[1] = exc->GS.freeVector.y;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SSWCI[]:      Set Single Width Cut In                                 */
-  /* Opcode range: 0x1E                                                    */
-  /* Stack:        f26.6 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SSWCI( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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 );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPON[]:     Set auto-FLIP to ON                                     */
-  /* Opcode range: 0x4D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_FLIPON( TT_ExecContext  exc )
-  {
-    exc->GS.auto_flip = TRUE;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
-  /* Opcode range: 0x4E                                                    */
-  /* Stack: -->                                                            */
-  /*                                                                       */
-  static void
-  Ins_FLIPOFF( TT_ExecContext  exc )
-  {
-    exc->GS.auto_flip = FALSE;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SANGW[]:      Set ANGle Weight                                        */
-  /* Opcode range: 0x7E                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SANGW( void )
-  {
-    /* instruction not supported anymore */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RTG[]:        Round To Grid                                           */
-  /* Opcode range: 0x18                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RTG( TT_ExecContext  exc )
-  {
-    exc->GS.round_state = TT_Round_To_Grid;
-    exc->func_round     = (TT_Round_Func)Round_To_Grid;
-  }
-
-
-  /*************************************************************************/
-  /* 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;
-  }
-
-
-  /*************************************************************************/
-  /* 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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RDTG[]:       Round Down To Grid                                      */
-  /* Opcode range: 0x7D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RDTG( TT_ExecContext  exc )
-  {
-    exc->GS.round_state = TT_Round_Down_To_Grid;
-    exc->func_round     = (TT_Round_Func)Round_Down_To_Grid;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SROUND[]:     Super ROUND                                             */
-  /* Opcode range: 0x76                                                    */
-  /* Stack:        Eint8 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SROUND( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    SetSuperRound( exc, 0x4000, args[0] );
-
-    exc->GS.round_state = TT_Round_Super;
-    exc->func_round     = (TT_Round_Func)Round_Super;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GC[a]:        Get Coordinate projected onto                           */
-  /* Opcode range: 0x46-0x47                                               */
-  /* Stack:        uint32 --> f26.6                                        */
-  /*                                                                       */
-  /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken     */
-  /*      along the dual projection vector!                                */
-  /*                                                                       */
-  static void
-  Ins_GC( TT_ExecContext  exc,
-          FT_Long*        args )
-  {
-    FT_ULong    L;
-    FT_F26Dot6  R;
-
-
-    L = (FT_ULong)args[0];
-
-    if ( BOUNDSL( L, exc->zp2.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      R = 0;
-    }
-    else
-    {
-      if ( exc->opcode & 1 )
-        R = FAST_DUALPROJ( &exc->zp2.org[L] );
-      else
-        R = FAST_PROJECT( &exc->zp2.cur[L] );
-    }
-
-    args[0] = R;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SCFS[]:       Set Coordinate From Stack                               */
-  /* Opcode range: 0x48                                                    */
-  /* Stack:        f26.6 uint32 -->                                        */
-  /*                                                                       */
-  /* Formula:                                                              */
-  /*                                                                       */
-  /*   OA := OA + ( value - OA.p )/( f.p ) * f                             */
-  /*                                                                       */
-  static void
-  Ins_SCFS( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_Long    K;
-    FT_UShort  L;
-
-
-    L = (FT_UShort)args[0];
-
-    if ( BOUNDS( L, exc->zp2.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    K = FAST_PROJECT( &exc->zp2.cur[L] );
-
-    exc->func_move( exc, &exc->zp2, L, args[1] - K );
-
-    /* UNDOCUMENTED!  The MS rasterizer does that with */
-    /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( exc->GS.gep2 == 0 )
-      exc->zp2.org[L] = exc->zp2.cur[L];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MD[a]:        Measure Distance                                        */
-  /* Opcode range: 0x49-0x4A                                               */
-  /* Stack:        uint32 uint32 --> f26.6                                 */
-  /*                                                                       */
-  /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along  */
-  /*                    the dual projection vector.                        */
-  /*                                                                       */
-  /* XXX: UNDOCUMENTED: Flag attributes are inverted!                      */
-  /*                      0 => measure distance in original outline        */
-  /*                      1 => measure distance in grid-fitted outline     */
-  /*                                                                       */
-  /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1!                   */
-  /*                                                                       */
-  static void
-  Ins_MD( TT_ExecContext  exc,
-          FT_Long*        args )
-  {
-    FT_UShort   K, L;
-    FT_F26Dot6  D;
-
-
-    K = (FT_UShort)args[1];
-    L = (FT_UShort)args[0];
-
-    if ( BOUNDS( L, exc->zp0.n_points ) ||
-         BOUNDS( K, exc->zp1.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      D = 0;
-    }
-    else
-    {
-      if ( exc->opcode & 1 )
-        D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
-      else
-      {
-        /* XXX: UNDOCUMENTED: twilight zone special case */
-
-        if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
-        {
-          FT_Vector*  vec1 = exc->zp0.org + L;
-          FT_Vector*  vec2 = exc->zp1.org + K;
-
-
-          D = DUALPROJ( vec1, vec2 );
-        }
-        else
-        {
-          FT_Vector*  vec1 = exc->zp0.orus + L;
-          FT_Vector*  vec2 = exc->zp1.orus + K;
-
-
-          if ( exc->metrics.x_scale == exc->metrics.y_scale )
-          {
-            /* this should be faster */
-            D = DUALPROJ( vec1, vec2 );
-            D = FT_MulFix( D, exc->metrics.x_scale );
-          }
-          else
-          {
-            FT_Vector  vec;
-
-
-            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 = FAST_DUALPROJ( &vec );
-          }
-        }
-      }
-    }
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING   &&
-         exc->ignore_x_mode &&
-         FT_ABS( D ) == 64  )
-      D += 1;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    args[0] = D;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SDPvTL[a]:    Set Dual PVector to Line                                */
-  /* Opcode range: 0x86-0x87                                               */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  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_Byte  opcode = exc->opcode;
-
-
-    p1 = (FT_UShort)args[1];
-    p2 = (FT_UShort)args[0];
-
-    if ( BOUNDS( p2, exc->zp1.n_points ) ||
-         BOUNDS( p1, exc->zp2.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    {
-      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 */
-      /* SVTCA[X], respectively.                 */
-      /*                                         */
-      /* Confirmed by Greg Hitchcock.            */
-
-      if ( A == 0 && B == 0 )
-      {
-        A      = 0x4000;
-        opcode = 0;
-      }
-    }
-
-    if ( ( opcode & 1 ) != 0 )
-    {
-      C =  B;   /* counter clockwise rotation */
-      B =  A;
-      A = -C;
-    }
-
-    Normalize( A, B, &exc->GS.dualVector );
-
-    {
-      FT_Vector*  v1 = exc->zp1.cur + p2;
-      FT_Vector*  v2 = exc->zp2.cur + p1;
-
-
-      A = v1->x - v2->x;
-      B = v1->y - v2->y;
-
-      if ( A == 0 && B == 0 )
-      {
-        A      = 0x4000;
-        opcode = 0;
-      }
-    }
-
-    if ( ( opcode & 1 ) != 0 )
-    {
-      C =  B;   /* counter clockwise rotation */
-      B =  A;
-      A = -C;
-    }
-
-    Normalize( A, B, &exc->GS.projVector );
-    Compute_Funcs( exc );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SZP0[]:       Set Zone Pointer 0                                      */
-  /* Opcode range: 0x13                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SZP0( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    switch ( (FT_Int)args[0] )
-    {
-    case 0:
-      exc->zp0 = exc->twilight;
-      break;
-
-    case 1:
-      exc->zp0 = exc->pts;
-      break;
-
-    default:
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    exc->GS.gep0 = (FT_UShort)args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SZP1[]:       Set Zone Pointer 1                                      */
-  /* Opcode range: 0x14                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SZP1( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    switch ( (FT_Int)args[0] )
-    {
-    case 0:
-      exc->zp1 = exc->twilight;
-      break;
-
-    case 1:
-      exc->zp1 = exc->pts;
-      break;
-
-    default:
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    exc->GS.gep1 = (FT_UShort)args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SZP2[]:       Set Zone Pointer 2                                      */
-  /* Opcode range: 0x15                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SZP2( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    switch ( (FT_Int)args[0] )
-    {
-    case 0:
-      exc->zp2 = exc->twilight;
-      break;
-
-    case 1:
-      exc->zp2 = exc->pts;
-      break;
-
-    default:
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    exc->GS.gep2 = (FT_UShort)args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SZPS[]:       Set Zone PointerS                                       */
-  /* Opcode range: 0x16                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SZPS( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    switch ( (FT_Int)args[0] )
-    {
-    case 0:
-      exc->zp0 = exc->twilight;
-      break;
-
-    case 1:
-      exc->zp0 = exc->pts;
-      break;
-
-    default:
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    exc->zp1 = exc->zp0;
-    exc->zp2 = exc->zp0;
-
-    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                                                    */
-  /* Stack:        int32 int32 -->                                         */
-  /*                                                                       */
-  static void
-  Ins_INSTCTRL( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    FT_ULong  K, L, Kf;
-
-
-    K = (FT_ULong)args[1];
-    L = (FT_ULong)args[0];
-
-    /* selector values cannot be `OR'ed;                 */
-    /* they are indices starting with index 1, not flags */
-    if ( K < 1 || K > 3 )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    /* convert index to flag value */
-    Kf = 1 << ( K - 1 );
-
-    if ( L != 0 )
-    {
-      /* arguments to selectors look like flag values */
-      if ( L != Kf )
-      {
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Invalid_Reference );
-        return;
-      }
-    }
-
-    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
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SCANCTRL[]:   SCAN ConTRoL                                            */
-  /* Opcode range: 0x85                                                    */
-  /* Stack:        uint32? -->                                             */
-  /*                                                                       */
-  static void
-  Ins_SCANCTRL( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    FT_Int  A;
-
-
-    /* Get Threshold */
-    A = (FT_Int)( args[0] & 0xFF );
-
-    if ( A == 0xFF )
-    {
-      exc->GS.scan_control = TRUE;
-      return;
-    }
-    else if ( A == 0 )
-    {
-      exc->GS.scan_control = FALSE;
-      return;
-    }
-
-    if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
-      exc->GS.scan_control = TRUE;
-
-    if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
-      exc->GS.scan_control = TRUE;
-
-    if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
-      exc->GS.scan_control = TRUE;
-
-    if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
-      exc->GS.scan_control = FALSE;
-
-    if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
-      exc->GS.scan_control = FALSE;
-
-    if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
-      exc->GS.scan_control = FALSE;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SCANTYPE[]:   SCAN TYPE                                               */
-  /* Opcode range: 0x8D                                                    */
-  /* Stack:        uint32? -->                                             */
-  /*                                                                       */
-  static void
-  Ins_SCANTYPE( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    if ( args[0] >= 0 )
-      exc->GS.scan_type = (FT_Int)args[0];
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MANAGING OUTLINES                                                     */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPPT[]:     FLIP PoinT                                              */
-  /* Opcode range: 0x80                                                    */
-  /* Stack:        uint32... -->                                           */
-  /*                                                                       */
-  static void
-  Ins_FLIPPT( TT_ExecContext  exc )
-  {
-    FT_UShort  point;
-
-
-    if ( exc->top < exc->GS.loop )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Too_Few_Arguments );
-      goto Fail;
-    }
-
-    while ( exc->GS.loop > 0 )
-    {
-      exc->args--;
-
-      point = (FT_UShort)exc->stack[exc->args];
-
-      if ( BOUNDS( point, exc->pts.n_points ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          exc->error = FT_THROW( Invalid_Reference );
-          return;
-        }
-      }
-      else
-        exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
-
-      exc->GS.loop--;
-    }
-
-  Fail:
-    exc->GS.loop = 1;
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPRGON[]:   FLIP RanGe ON                                           */
-  /* Opcode range: 0x81                                                    */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_FLIPRGON( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    FT_UShort  I, K, L;
-
-
-    K = (FT_UShort)args[1];
-    L = (FT_UShort)args[0];
-
-    if ( BOUNDS( K, exc->pts.n_points ) ||
-         BOUNDS( L, exc->pts.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    for ( I = L; I <= K; I++ )
-      exc->pts.tags[I] |= FT_CURVE_TAG_ON;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPRGOFF:    FLIP RanGe OFF                                          */
-  /* Opcode range: 0x82                                                    */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_FLIPRGOFF( TT_ExecContext  exc,
-                 FT_Long*        args )
-  {
-    FT_UShort  I, K, L;
-
-
-    K = (FT_UShort)args[1];
-    L = (FT_UShort)args[0];
-
-    if ( BOUNDS( K, exc->pts.n_points ) ||
-         BOUNDS( L, exc->pts.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    for ( I = L; I <= K; I++ )
-      exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
-  }
-
-
-  static FT_Bool
-  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 ( exc->opcode & 1 )
-    {
-      zp = exc->zp0;
-      p  = exc->GS.rp1;
-    }
-    else
-    {
-      zp = exc->zp1;
-      p  = exc->GS.rp2;
-    }
-
-    if ( BOUNDS( p, zp.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      *refp = 0;
-      return FAILURE;
-    }
-
-    *zone = zp;
-    *refp = p;
-
-    d = PROJECT( zp.cur + p, zp.org + 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;
-  }
-
-
-  static void
-  Move_Zp2_Point( TT_ExecContext  exc,
-                  FT_UShort       point,
-                  FT_F26Dot6      dx,
-                  FT_F26Dot6      dy,
-                  FT_Bool         touch )
-  {
-    if ( exc->GS.freeVector.x != 0 )
-    {
-      exc->zp2.cur[point].x += dx;
-      if ( touch )
-        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
-    }
-
-    if ( exc->GS.freeVector.y != 0 )
-    {
-      exc->zp2.cur[point].y += dy;
-      if ( touch )
-        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SHP[a]:       SHift Point by the last point                           */
-  /* Opcode range: 0x32-0x33                                               */
-  /* Stack:        uint32... -->                                           */
-  /*                                                                       */
-  static void
-  Ins_SHP( TT_ExecContext  exc )
-  {
-    TT_GlyphZoneRec  zp;
-    FT_UShort        refp;
-
-    FT_F26Dot6       dx, dy;
-    FT_UShort        point;
-
-
-    if ( exc->top < exc->GS.loop )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
-      return;
-
-    while ( exc->GS.loop > 0 )
-    {
-      exc->args--;
-      point = (FT_UShort)exc->stack[exc->args];
-
-      if ( BOUNDS( point, exc->zp2.n_points ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          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   &&
-           exc->ignore_x_mode )
-        Move_Zp2_Point( exc, point, 0, dy, TRUE );
-      else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-      exc->GS.loop--;
-    }
-
-  Fail:
-    exc->GS.loop = 1;
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SHC[a]:       SHift Contour                                           */
-  /* Opcode range: 0x34-35                                                 */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual)     */
-  /*               contour in the twilight zone, namely contour number     */
-  /*               zero which includes all points of it.                   */
-  /*                                                                       */
-  static void
-  Ins_SHC( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    TT_GlyphZoneRec  zp;
-    FT_UShort        refp;
-    FT_F26Dot6       dx, dy;
-
-    FT_Short         contour, bounds;
-    FT_UShort        start, limit, i;
-
-
-    contour = (FT_Short)args[0];
-    bounds  = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
-
-    if ( BOUNDS( contour, bounds ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
-      return;
-
-    if ( contour == 0 )
-      start = 0;
-    else
-      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 ( exc->GS.gep2 == 0 )
-      limit = exc->zp2.n_points;
-    else
-      limit = (FT_UShort)( exc->zp2.contours[contour] -
-                           exc->zp2.first_point + 1 );
-
-    for ( i = start; i < limit; i++ )
-    {
-      if ( zp.cur != exc->zp2.cur || refp != i )
-        Move_Zp2_Point( exc, i, dx, dy, TRUE );
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SHZ[a]:       SHift Zone                                              */
-  /* Opcode range: 0x36-37                                                 */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SHZ( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    TT_GlyphZoneRec  zp;
-    FT_UShort        refp;
-    FT_F26Dot6       dx,
-                     dy;
-
-    FT_UShort        limit, i;
-
-
-    if ( BOUNDS( args[0], 2 ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    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 ( 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 != exc->zp2.cur || refp != i )
-        Move_Zp2_Point( exc, i, dx, dy, FALSE );
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SHPIX[]:      SHift points by a PIXel amount                          */
-  /* Opcode range: 0x38                                                    */
-  /* Stack:        f26.6 uint32... -->                                     */
-  /*                                                                       */
-  static void
-  Ins_SHPIX( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    FT_F26Dot6  dx, dy;
-    FT_UShort   point;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_Int      B1, B2;
-#endif
-
-
-    if ( exc->top < exc->GS.loop + 1 )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
-    dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
-
-    while ( exc->GS.loop > 0 )
-    {
-      exc->args--;
-
-      point = (FT_UShort)exc->stack[exc->args];
-
-      if ( BOUNDS( point, exc->zp2.n_points ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          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   &&
-             exc->ignore_x_mode )
-        {
-          /* save point for later comparison */
-          if ( exc->GS.freeVector.y != 0 )
-            B1 = exc->zp2.cur[point].y;
-          else
-            B1 = exc->zp2.cur[point].x;
-
-          if ( !exc->face->sph_compatibility_mode &&
-               exc->GS.freeVector.y != 0          )
-          {
-            Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-            /* save new point */
-            if ( exc->GS.freeVector.y != 0 )
-            {
-              B2 = exc->zp2.cur[point].y;
-
-              /* reverse any disallowed moves */
-              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 ( exc->face->sph_compatibility_mode )
-          {
-            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 ( 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 ( !( 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 ( exc->GS.freeVector.y != 0 )
-            {
-              B2 = exc->zp2.cur[point].y;
-
-              /* reverse any disallowed moves */
-              if ( ( B1 & 63 ) == 0 &&
-                   ( B2 & 63 ) != 0 &&
-                   B1 != B2         )
-                Move_Zp2_Point( exc, point, 0, -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( exc, point, dx, dy, TRUE );
-      }
-
-    Skip:
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-      Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-      exc->GS.loop--;
-    }
-
-  Fail:
-    exc->GS.loop = 1;
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MSIRP[a]:     Move Stack Indirect Relative Position                   */
-  /* Opcode range: 0x3A-0x3B                                               */
-  /* Stack:        f26.6 uint32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_MSIRP( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    FT_UShort   point;
-    FT_F26Dot6  distance;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_F26Dot6  control_value_cutin = 0; /* pacify compiler */
-
-
-    if ( SUBPIXEL_HINTING )
-    {
-      control_value_cutin = exc->GS.control_value_cutin;
-
-      if ( exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-    }
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    point = (FT_UShort)args[0];
-
-    if ( BOUNDS( point,       exc->zp1.n_points ) ||
-         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
-    {
-      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 ( exc->GS.gep1 == 0 )
-    {
-      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 = 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                                    &&
-         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 */
-
-    exc->func_move( exc, &exc->zp1, point, args[1] - distance );
-
-    exc->GS.rp1 = exc->GS.rp0;
-    exc->GS.rp2 = point;
-
-    if ( ( exc->opcode & 1 ) != 0 )
-      exc->GS.rp0 = point;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MDAP[a]:      Move Direct Absolute Point                              */
-  /* Opcode range: 0x2E-0x2F                                               */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_MDAP( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_UShort   point;
-    FT_F26Dot6  cur_dist;
-    FT_F26Dot6  distance;
-
-
-    point = (FT_UShort)args[0];
-
-    if ( BOUNDS( point, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    if ( ( exc->opcode & 1 ) != 0 )
-    {
-      cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
-        distance = Round_None(
-                     exc,
-                     cur_dist,
-                     exc->tt_metrics.compensations[0] ) - cur_dist;
-      else
-#endif
-        distance = exc->func_round(
-                     exc,
-                     cur_dist,
-                     exc->tt_metrics.compensations[0] ) - cur_dist;
-    }
-    else
-      distance = 0;
-
-    exc->func_move( exc, &exc->zp0, point, distance );
-
-    exc->GS.rp0 = point;
-    exc->GS.rp1 = point;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MIAP[a]:      Move Indirect Absolute Point                            */
-  /* Opcode range: 0x3E-0x3F                                               */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_MIAP( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_ULong    cvtEntry;
-    FT_UShort   point;
-    FT_F26Dot6  distance;
-    FT_F26Dot6  org_dist;
-    FT_F26Dot6  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                                   &&
-         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,     exc->zp0.n_points ) ||
-         BOUNDSL( cvtEntry, exc->cvtSize )      )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    /* UNDOCUMENTED!                                                      */
-    /*                                                                    */
-    /* The behaviour of an MIAP instruction is quite different when used  */
-    /* in the twilight zone.                                              */
-    /*                                                                    */
-    /* First, no control value cut-in test is performed as it would fail  */
-    /* anyway.  Second, the original point, i.e. (org_x,org_y) of         */
-    /* zp0.point, is set to the absolute, unrounded distance found in the */
-    /* CVT.                                                               */
-    /*                                                                    */
-    /* This is used in the CVT programs of the Microsoft fonts Arial,     */
-    /* Times, etc., in order to re-adjust some key font heights.  It      */
-    /* allows the use of the IP instruction in the twilight zone, which   */
-    /* otherwise would be invalid according to the specification.         */
-    /*                                                                    */
-    /* We implement it with a special sequence for the twilight zone.     */
-    /* This is a bad hack, but it seems to work.                          */
-    /*                                                                    */
-    /* Confirmed by Greg Hitchcock.                                       */
-
-    distance = exc->func_read_cvt( exc, cvtEntry );
-
-    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                      ||
-           ( !exc->ignore_x_mode                ||
-             !exc->face->sph_compatibility_mode ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        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                               &&
-         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 = FAST_PROJECT( &exc->zp0.cur[point] );
-
-    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          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
-        distance = Round_None( exc,
-                               distance,
-                               exc->tt_metrics.compensations[0] );
-      else
-#endif
-        distance = exc->func_round( exc,
-                                    distance,
-                                    exc->tt_metrics.compensations[0] );
-    }
-
-    exc->func_move( exc, &exc->zp0, point, distance - org_dist );
-
-  Fail:
-    exc->GS.rp0 = point;
-    exc->GS.rp1 = point;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MDRP[abcde]:  Move Direct Relative Point                              */
-  /* Opcode range: 0xC0-0xDF                                               */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_MDRP( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_UShort   point;
-    FT_F26Dot6  org_dist, distance, minimum_distance;
-
-
-    minimum_distance = exc->GS.minimum_distance;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    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,       exc->zp1.n_points ) ||
-         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    /* XXX: Is there some undocumented feature while in the */
-    /*      twilight zone?                                  */
-
-    /* XXX: UNDOCUMENTED: twilight zone special case */
-
-    if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
-    {
-      FT_Vector*  vec1 = &exc->zp1.org[point];
-      FT_Vector*  vec2 = &exc->zp0.org[exc->GS.rp0];
-
-
-      org_dist = DUALPROJ( vec1, vec2 );
-    }
-    else
-    {
-      FT_Vector*  vec1 = &exc->zp1.orus[point];
-      FT_Vector*  vec2 = &exc->zp0.orus[exc->GS.rp0];
-
-
-      if ( exc->metrics.x_scale == exc->metrics.y_scale )
-      {
-        /* this should be faster */
-        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, exc->metrics.x_scale );
-        vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
-
-        org_dist = FAST_DUALPROJ( &vec );
-      }
-    }
-
-    /* single width cut-in test */
-
-    if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
-         exc->GS.single_width_cutin )
-    {
-      if ( org_dist >= 0 )
-        org_dist = exc->GS.single_width_value;
-      else
-        org_dist = -exc->GS.single_width_value;
-    }
-
-    /* round flag */
-
-    if ( ( exc->opcode & 4 ) != 0 )
-    {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
-        distance = Round_None(
-                     exc,
-                     org_dist,
-                     exc->tt_metrics.compensations[exc->opcode & 3] );
-      else
-#endif
-        distance = exc->func_round(
-                     exc,
-                     org_dist,
-                     exc->tt_metrics.compensations[exc->opcode & 3] );
-    }
-    else
-      distance = Round_None(
-                   exc,
-                   org_dist,
-                   exc->tt_metrics.compensations[exc->opcode & 3] );
-
-    /* minimum distance flag */
-
-    if ( ( exc->opcode & 8 ) != 0 )
-    {
-      if ( org_dist >= 0 )
-      {
-        if ( distance < minimum_distance )
-          distance = minimum_distance;
-      }
-      else
-      {
-        if ( distance > -minimum_distance )
-          distance = -minimum_distance;
-      }
-    }
-
-    /* now move the point */
-
-    org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
-
-    exc->func_move( exc, &exc->zp1, point, distance - org_dist );
-
-  Fail:
-    exc->GS.rp1 = exc->GS.rp0;
-    exc->GS.rp2 = point;
-
-    if ( ( exc->opcode & 16 ) != 0 )
-      exc->GS.rp0 = point;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MIRP[abcde]:  Move Indirect Relative Point                            */
-  /* Opcode range: 0xE0-0xFF                                               */
-  /* Stack:        int32? uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_MIRP( TT_ExecContext  exc,
-            FT_Long*        args )
-  {
-    FT_UShort   point;
-    FT_ULong    cvtEntry;
-
-    FT_F26Dot6  cvt_dist,
-                distance,
-                cur_dist,
-                org_dist,
-                control_value_cutin,
-                minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_Int      B1           = 0; /* pacify compiler */
-    FT_Int      B2           = 0;
-    FT_Bool     reverse_move = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-    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                                   &&
-         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,       exc->zp1.n_points ) ||
-         BOUNDSL( cvtEntry,   exc->cvtSize + 1 )  ||
-         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    if ( !cvtEntry )
-      cvt_dist = 0;
-    else
-      cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
-
-    /* single width test */
-
-    if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
-         exc->GS.single_width_cutin )
-    {
-      if ( cvt_dist >= 0 )
-        cvt_dist =  exc->GS.single_width_value;
-      else
-        cvt_dist = -exc->GS.single_width_value;
-    }
-
-    /* UNDOCUMENTED!  The MS rasterizer does that with */
-    /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( exc->GS.gep1 == 0 )
-    {
-      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 = 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 ( exc->GS.auto_flip )
-    {
-      if ( ( org_dist ^ cvt_dist ) < 0 )
-        cvt_dist = -cvt_dist;
-    }
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    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;
-      else if ( cur_dist > 64 && cur_dist < 84 )
-        cvt_dist += 32;
-    }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    /* control value cut-in and round */
-
-    if ( ( exc->opcode & 4 ) != 0 )
-    {
-      /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */
-      /*      refer to the same zone.                                  */
-
-      if ( exc->GS.gep0 == exc->GS.gep1 )
-      {
-        /* XXX: According to Greg Hitchcock, the following wording is */
-        /*      the right one:                                        */
-        /*                                                            */
-        /*        When the absolute difference between the value in   */
-        /*        the table [CVT] and the measurement directly from   */
-        /*        the outline is _greater_ than the cut_in value, the */
-        /*        outline measurement is used.                        */
-        /*                                                            */
-        /*      This is from `instgly.doc'.  The description in       */
-        /*      `ttinst2.doc', version 1.66, is thus incorrect since  */
-        /*      it implies `>=' instead of `>'.                       */
-
-        if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
-          cvt_dist = org_dist;
-      }
-
-      distance = exc->func_round(
-                   exc,
-                   cvt_dist,
-                   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             &&
-           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(
-                   exc,
-                   cvt_dist,
-                   exc->tt_metrics.compensations[exc->opcode & 3] );
-    }
-
-    /* minimum distance test */
-
-    if ( ( exc->opcode & 8 ) != 0 )
-    {
-      if ( org_dist >= 0 )
-      {
-        if ( distance < minimum_distance )
-          distance = minimum_distance;
-      }
-      else
-      {
-        if ( distance > -minimum_distance )
-          distance = -minimum_distance;
-      }
-    }
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING )
-    {
-      B1 = exc->zp1.cur[point].y;
-
-      /* Round moves if necessary */
-      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 ( 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 */
-
-    exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING )
-    {
-      B2 = exc->zp1.cur[point].y;
-
-      /* Reverse move if necessary */
-      if ( exc->ignore_x_mode )
-      {
-        if ( exc->face->sph_compatibility_mode &&
-             exc->GS.freeVector.y != 0         &&
-             ( B1 & 63 ) == 0                  &&
-             ( B2 & 63 ) != 0                  )
-          reverse_move = TRUE;
-
-        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 )
-        exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
-    }
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-  Fail:
-    exc->GS.rp1 = exc->GS.rp0;
-
-    if ( ( exc->opcode & 16 ) != 0 )
-      exc->GS.rp0 = point;
-
-    exc->GS.rp2 = point;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ALIGNRP[]:    ALIGN Relative Point                                    */
-  /* Opcode range: 0x3C                                                    */
-  /* Stack:        uint32 uint32... -->                                    */
-  /*                                                                       */
-  static void
-  Ins_ALIGNRP( TT_ExecContext  exc )
-  {
-    FT_UShort   point;
-    FT_F26Dot6  distance;
-
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                          &&
-         exc->ignore_x_mode                                        &&
-         exc->iup_called                                           &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
-    {
-      exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    if ( exc->top < exc->GS.loop                  ||
-         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    while ( exc->GS.loop > 0 )
-    {
-      exc->args--;
-
-      point = (FT_UShort)exc->stack[exc->args];
-
-      if ( BOUNDS( point, exc->zp1.n_points ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          exc->error = FT_THROW( Invalid_Reference );
-          return;
-        }
-      }
-      else
-      {
-        distance = PROJECT( exc->zp1.cur + point,
-                            exc->zp0.cur + exc->GS.rp0 );
-
-        exc->func_move( exc, &exc->zp1, point, -distance );
-      }
-
-      exc->GS.loop--;
-    }
-
-  Fail:
-    exc->GS.loop = 1;
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ISECT[]:      moves point to InterSECTion                             */
-  /* Opcode range: 0x0F                                                    */
-  /* Stack:        5 * uint32 -->                                          */
-  /*                                                                       */
-  static void
-  Ins_ISECT( TT_ExecContext  exc,
-             FT_Long*        args )
-  {
-    FT_UShort   point,
-                a0, a1,
-                b0, b1;
-
-    FT_F26Dot6  discriminant, dotproduct;
-
-    FT_F26Dot6  dx,  dy,
-                dax, day,
-                dbx, dby;
-
-    FT_F26Dot6  val;
-
-    FT_Vector   R;
-
-
-    point = (FT_UShort)args[0];
-
-    a0 = (FT_UShort)args[1];
-    a1 = (FT_UShort)args[2];
-    b0 = (FT_UShort)args[3];
-    b1 = (FT_UShort)args[4];
-
-    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 ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    /* Cramer's rule */
-
-    dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
-    dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
-
-    dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
-    day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
-
-    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 );
-    dotproduct   = FT_MulDiv( dax, dbx, 0x40 ) +
-                   FT_MulDiv( day, dby, 0x40 );
-
-    /* The discriminant above is actually a cross product of vectors     */
-    /* da and db. Together with the dot product, they can be used as     */
-    /* surrogates for sine and cosine of the angle between the vectors.  */
-    /* Indeed,                                                           */
-    /*       dotproduct   = |da||db|cos(angle)                           */
-    /*       discriminant = |da||db|sin(angle)     .                     */
-    /* We use these equations to reject grazing intersections by         */
-    /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */
-    if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) )
-    {
-      val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 );
-
-      R.x = FT_MulDiv( val, dax, discriminant );
-      R.y = FT_MulDiv( val, day, discriminant );
-
-      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 */
-
-      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;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ALIGNPTS[]:   ALIGN PoinTS                                            */
-  /* Opcode range: 0x27                                                    */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_ALIGNPTS( TT_ExecContext  exc,
-                FT_Long*        args )
-  {
-    FT_UShort   p1, p2;
-    FT_F26Dot6  distance;
-
-
-    p1 = (FT_UShort)args[0];
-    p2 = (FT_UShort)args[1];
-
-    if ( BOUNDS( p1, exc->zp1.n_points ) ||
-         BOUNDS( p2, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
-
-    exc->func_move( exc, &exc->zp1, p1, distance );
-    exc->func_move( exc, &exc->zp0, p2, -distance );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* IP[]:         Interpolate Point                                       */
-  /* Opcode range: 0x39                                                    */
-  /* Stack:        uint32... -->                                           */
-  /*                                                                       */
-
-  /* SOMETIMES, DUMBER CODE IS BETTER CODE */
-
-  static void
-  Ins_IP( TT_ExecContext  exc )
-  {
-    FT_F26Dot6  old_range, cur_range;
-    FT_Vector*  orus_base;
-    FT_Vector*  cur_base;
-    FT_Int      twilight;
-
-
-    if ( exc->top < exc->GS.loop )
-    {
-      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 exc->twilight.orus[n] is (0,0),
-     * for every n.
-     */
-    twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
-
-    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-
-    if ( twilight )
-      orus_base = &exc->zp0.org[exc->GS.rp1];
-    else
-      orus_base = &exc->zp0.orus[exc->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( exc->GS.rp1, exc->zp0.n_points ) ||
-         BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
-    {
-      old_range = 0;
-      cur_range = 0;
-    }
-    else
-    {
-      if ( twilight )
-        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( 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 = FAST_DUALPROJ( &vec );
-      }
-
-      cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
-    }
-
-    for ( ; exc->GS.loop > 0; --exc->GS.loop )
-    {
-      FT_UInt     point = (FT_UInt)exc->stack[--exc->args];
-      FT_F26Dot6  org_dist, cur_dist, new_dist;
-
-
-      /* check point bounds */
-      if ( BOUNDS( point, exc->zp2.n_points ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          exc->error = FT_THROW( Invalid_Reference );
-          return;
-        }
-        continue;
-      }
-
-      if ( twilight )
-        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( 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 = FAST_DUALPROJ( &vec );
-      }
-
-      cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
-
-      if ( org_dist )
-      {
-        if ( old_range )
-          new_dist = FT_MulDiv( org_dist, cur_range, old_range );
-        else
-        {
-          /* This is the same as what MS does for the invalid case:  */
-          /*                                                         */
-          /*   delta = (Original_Pt - Original_RP1) -                */
-          /*           (Current_Pt - Current_RP1)         ;          */
-          /*                                                         */
-          /* In FreeType speak:                                      */
-          /*                                                         */
-          /*   delta = org_dist - cur_dist          .                */
-          /*                                                         */
-          /* We move `point' by `new_dist - cur_dist' after leaving  */
-          /* this block, thus we have                                */
-          /*                                                         */
-          /*   new_dist - cur_dist = delta                   ,       */
-          /*   new_dist - cur_dist = org_dist - cur_dist     ,       */
-          /*              new_dist = org_dist                .       */
-
-          new_dist = org_dist;
-        }
-      }
-      else
-        new_dist = 0;
-
-      exc->func_move( exc,
-                      &exc->zp2,
-                      (FT_UShort)point,
-                      new_dist - cur_dist );
-    }
-
-  Fail:
-    exc->GS.loop = 1;
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* UTP[a]:       UnTouch Point                                           */
-  /* Opcode range: 0x29                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_UTP( TT_ExecContext  exc,
-           FT_Long*        args )
-  {
-    FT_UShort  point;
-    FT_Byte    mask;
-
-
-    point = (FT_UShort)args[0];
-
-    if ( BOUNDS( point, exc->zp0.n_points ) )
-    {
-      if ( exc->pedantic_hinting )
-        exc->error = FT_THROW( Invalid_Reference );
-      return;
-    }
-
-    mask = 0xFF;
-
-    if ( exc->GS.freeVector.x != 0 )
-      mask &= ~FT_CURVE_TAG_TOUCH_X;
-
-    if ( exc->GS.freeVector.y != 0 )
-      mask &= ~FT_CURVE_TAG_TOUCH_Y;
-
-    exc->zp0.tags[point] &= mask;
-  }
-
-
-  /* Local variables for Ins_IUP: */
-  typedef struct  IUP_WorkerRec_
-  {
-    FT_Vector*  orgs;   /* original and current coordinate */
-    FT_Vector*  curs;   /* arrays                          */
-    FT_Vector*  orus;
-    FT_UInt     max_points;
-
-  } IUP_WorkerRec, *IUP_Worker;
-
-
-  static void
-  _iup_worker_shift( IUP_Worker  worker,
-                     FT_UInt     p1,
-                     FT_UInt     p2,
-                     FT_UInt     p )
-  {
-    FT_UInt     i;
-    FT_F26Dot6  dx;
-
-
-    dx = worker->curs[p].x - worker->orgs[p].x;
-    if ( dx != 0 )
-    {
-      for ( i = p1; i < p; i++ )
-        worker->curs[i].x += dx;
-
-      for ( i = p + 1; i <= p2; i++ )
-        worker->curs[i].x += dx;
-    }
-  }
-
-
-  static void
-  _iup_worker_interpolate( IUP_Worker  worker,
-                           FT_UInt     p1,
-                           FT_UInt     p2,
-                           FT_UInt     ref1,
-                           FT_UInt     ref2 )
-  {
-    FT_UInt     i;
-    FT_F26Dot6  orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
-
-
-    if ( p1 > p2 )
-      return;
-
-    if ( BOUNDS( ref1, worker->max_points ) ||
-         BOUNDS( ref2, worker->max_points ) )
-      return;
-
-    orus1 = worker->orus[ref1].x;
-    orus2 = worker->orus[ref2].x;
-
-    if ( orus1 > orus2 )
-    {
-      FT_F26Dot6  tmp_o;
-      FT_UInt     tmp_r;
-
-
-      tmp_o = orus1;
-      orus1 = orus2;
-      orus2 = tmp_o;
-
-      tmp_r = ref1;
-      ref1  = ref2;
-      ref2  = tmp_r;
-    }
-
-    org1   = worker->orgs[ref1].x;
-    org2   = worker->orgs[ref2].x;
-    cur1   = worker->curs[ref1].x;
-    cur2   = worker->curs[ref2].x;
-    delta1 = cur1 - org1;
-    delta2 = cur2 - org2;
-
-    if ( cur1 == cur2 || orus1 == orus2 )
-    {
-
-      /* trivial snap or shift of untouched points */
-      for ( i = p1; i <= p2; i++ )
-      {
-        FT_F26Dot6  x = worker->orgs[i].x;
-
-
-        if ( x <= org1 )
-          x += delta1;
-
-        else if ( x >= org2 )
-          x += delta2;
-
-        else
-          x = cur1;
-
-        worker->curs[i].x = x;
-      }
-    }
-    else
-    {
-      FT_Fixed  scale       = 0;
-      FT_Bool   scale_valid = 0;
-
-
-      /* interpolation */
-      for ( i = p1; i <= p2; i++ )
-      {
-        FT_F26Dot6  x = worker->orgs[i].x;
-
-
-        if ( x <= org1 )
-          x += delta1;
-
-        else if ( x >= org2 )
-          x += delta2;
-
-        else
-        {
-          if ( !scale_valid )
-          {
-            scale_valid = 1;
-            scale       = FT_DivFix( cur2 - cur1, orus2 - orus1 );
-          }
-
-          x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
-        }
-        worker->curs[i].x = x;
-      }
-    }
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* IUP[a]:       Interpolate Untouched Points                            */
-  /* Opcode range: 0x30-0x31                                               */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_IUP( TT_ExecContext  exc )
-  {
-    IUP_WorkerRec  V;
-    FT_Byte        mask;
-
-    FT_UInt   first_point;   /* first point of contour        */
-    FT_UInt   end_point;     /* end point (last+1) of contour */
-
-    FT_UInt   first_touched; /* first touched point in contour   */
-    FT_UInt   cur_touched;   /* current touched point in contour */
-
-    FT_UInt   point;         /* current point   */
-    FT_Short  contour;       /* current contour */
-
-
-    /* ignore empty outlines */
-    if ( exc->pts.n_contours == 0 )
-      return;
-
-    if ( exc->opcode & 1 )
-    {
-      mask   = FT_CURVE_TAG_TOUCH_X;
-      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*)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 = exc->pts.n_points;
-
-    contour = 0;
-    point   = 0;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING   &&
-         exc->ignore_x_mode )
-    {
-      exc->iup_called = TRUE;
-      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
-        return;
-    }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    do
-    {
-      end_point   = exc->pts.contours[contour] - exc->pts.first_point;
-      first_point = point;
-
-      if ( BOUNDS( end_point, exc->pts.n_points ) )
-        end_point = exc->pts.n_points - 1;
-
-      while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
-        point++;
-
-      if ( point <= end_point )
-      {
-        first_touched = point;
-        cur_touched   = point;
-
-        point++;
-
-        while ( point <= end_point )
-        {
-          if ( ( exc->pts.tags[point] & mask ) != 0 )
-          {
-            _iup_worker_interpolate( &V,
-                                     cur_touched + 1,
-                                     point - 1,
-                                     cur_touched,
-                                     point );
-            cur_touched = point;
-          }
-
-          point++;
-        }
-
-        if ( cur_touched == first_touched )
-          _iup_worker_shift( &V, first_point, end_point, cur_touched );
-        else
-        {
-          _iup_worker_interpolate( &V,
-                                   (FT_UShort)( cur_touched + 1 ),
-                                   end_point,
-                                   cur_touched,
-                                   first_touched );
-
-          if ( first_touched > 0 )
-            _iup_worker_interpolate( &V,
-                                     first_point,
-                                     first_touched - 1,
-                                     cur_touched,
-                                     first_touched );
-        }
-      }
-      contour++;
-    } while ( contour < exc->pts.n_contours );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DELTAPn[]:    DELTA exceptions P1, P2, P3                             */
-  /* Opcode range: 0x5D,0x71,0x72                                          */
-  /* Stack:        uint32 (2 * uint32)... -->                              */
-  /*                                                                       */
-  static void
-  Ins_DELTAP( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    FT_ULong   nump, k;
-    FT_UShort  A;
-    FT_ULong   C, P;
-    FT_Long    B;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_UShort  B1, B2;
-
-
-    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 */
-
-    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 ( exc->args < 2 )
-      {
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Too_Few_Arguments );
-        exc->args = 0;
-        goto Fail;
-      }
-
-      exc->args -= 2;
-
-      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   */
-      /*      point reference is off limit, rather than returning an */
-      /*      error.  As a delta instruction doesn't change a glyph  */
-      /*      in great ways, this shouldn't be a problem.            */
-
-      if ( !BOUNDS( A, exc->zp0.n_points ) )
-      {
-        C = ( (FT_ULong)B & 0xF0 ) >> 4;
-
-        switch ( exc->opcode )
-        {
-        case 0x5D:
-          break;
-
-        case 0x71:
-          C += 16;
-          break;
-
-        case 0x72:
-          C += 32;
-          break;
-        }
-
-        C += exc->GS.delta_base;
-
-        if ( P == C )
-        {
-          B = ( (FT_ULong)B & 0xF ) - 8;
-          if ( B >= 0 )
-            B++;
-          B *= 1L << ( 6 - exc->GS.delta_shift );
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-          if ( SUBPIXEL_HINTING )
-          {
-            /*
-             *  Allow delta move if
-             *
-             *  - not using ignore_x_mode rendering,
-             *  - glyph is specifically set to allow it, or
-             *  - glyph is composite and freedom vector is not in subpixel
-             *    direction.
-             */
-            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 ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
-            {
-              /* save the y value of the point now; compare after move */
-              B1 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* Standard subpixel hinting: Allow y move for y-touched */
-              /* points.  This messes up DejaVu ...                    */
-              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 ( exc->face->sph_compatibility_mode                        &&
-                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
-              {
-                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 ( !exc->iup_called                            &&
-                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                  exc->func_move( exc, &exc->zp0, A, B );
-              }
-
-              B2 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* Reverse this move if it results in a disallowed move */
-              if ( exc->GS.freeVector.y != 0                          &&
-                   ( ( exc->face->sph_compatibility_mode          &&
-                       ( B1 & 63 ) == 0                           &&
-                       ( B2 & 63 ) != 0                           ) ||
-                     ( ( exc->sph_tweak_flags                   &
-                         SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
-                       ( B1 & 63 ) != 0                           &&
-                       ( B2 & 63 ) != 0                           ) ) )
-                exc->func_move( exc, &exc->zp0, A, -B );
-            }
-          }
-          else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-            exc->func_move( exc, &exc->zp0, A, B );
-        }
-      }
-      else
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Invalid_Reference );
-    }
-
-  Fail:
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DELTACn[]:    DELTA exceptions C1, C2, C3                             */
-  /* Opcode range: 0x73,0x74,0x75                                          */
-  /* Stack:        uint32 (2 * uint32)... -->                              */
-  /*                                                                       */
-  static void
-  Ins_DELTAC( TT_ExecContext  exc,
-              FT_Long*        args )
-  {
-    FT_ULong  nump, k;
-    FT_ULong  A, C, P;
-    FT_Long   B;
-
-
-    P    = (FT_ULong)exc->func_cur_ppem( exc );
-    nump = (FT_ULong)args[0];
-
-    for ( k = 1; k <= nump; k++ )
-    {
-      if ( exc->args < 2 )
-      {
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Too_Few_Arguments );
-        exc->args = 0;
-        goto Fail;
-      }
-
-      exc->args -= 2;
-
-      A = (FT_ULong)exc->stack[exc->args + 1];
-      B = exc->stack[exc->args];
-
-      if ( BOUNDSL( A, exc->cvtSize ) )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          exc->error = FT_THROW( Invalid_Reference );
-          return;
-        }
-      }
-      else
-      {
-        C = ( (FT_ULong)B & 0xF0 ) >> 4;
-
-        switch ( exc->opcode )
-        {
-        case 0x73:
-          break;
-
-        case 0x74:
-          C += 16;
-          break;
-
-        case 0x75:
-          C += 32;
-          break;
-        }
-
-        C += exc->GS.delta_base;
-
-        if ( P == C )
-        {
-          B = ( (FT_ULong)B & 0xF ) - 8;
-          if ( B >= 0 )
-            B++;
-          B *= 1L << ( 6 - exc->GS.delta_shift );
-
-          exc->func_move_cvt( exc, A, B );
-        }
-      }
-    }
-
-  Fail:
-    exc->new_top = exc->args;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* MISC. INSTRUCTIONS                                                    */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GETINFO[]:    GET INFOrmation                                         */
-  /* 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( TT_ExecContext  exc,
-               FT_Long*        args )
-  {
-    FT_Long  K;
-
-
-    K = 0;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    /********************************/
-    /* RASTERIZER VERSION           */
-    /* Selector Bit:  0             */
-    /* Return Bit(s): 0-7           */
-    /*                              */
-    if ( SUBPIXEL_HINTING      &&
-         ( args[0] & 1 ) != 0  &&
-         exc->subpixel_hinting )
-    {
-      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 */
-      if ( ( args[0] & 1 ) != 0 )
-        K = TT_INTERPRETER_VERSION_35;
-
-    /********************************/
-    /* GLYPH ROTATED                */
-    /* Selector Bit:  1             */
-    /* Return Bit(s): 8             */
-    /*                              */
-    if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
-      K |= 0x80;
-
-    /********************************/
-    /* GLYPH STRETCHED              */
-    /* Selector Bit:  2             */
-    /* Return Bit(s): 9             */
-    /*                              */
-    if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
-      K |= 1 << 8;
-
-    /********************************/
-    /* HINTING FOR GRAYSCALE        */
-    /* Selector Bit:  5             */
-    /* Return Bit(s): 12            */
-    /*                              */
-    if ( ( args[0] & 32 ) != 0 && exc->grayscale )
-      K |= 1 << 12;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-    if ( SUBPIXEL_HINTING                                     &&
-         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
-    {
-
-      if ( exc->rasterizer_version >= 37 )
-      {
-        /********************************/
-        /* HINTING FOR SUBPIXEL         */
-        /* Selector Bit:  6             */
-        /* Return Bit(s): 13            */
-        /*                              */
-        if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
-          K |= 1 << 13;
-
-        /********************************/
-        /* COMPATIBLE WIDTHS ENABLED    */
-        /* Selector Bit:  7             */
-        /* Return Bit(s): 14            */
-        /*                              */
-        /* Functionality still needs to be added */
-        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
-          K |= 1 << 14;
-
-        /********************************/
-        /* VERTICAL LCD SUBPIXELS?      */
-        /* Selector Bit:  8             */
-        /* Return Bit(s): 15            */
-        /*                              */
-        /* Functionality still needs to be added */
-        if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
-          K |= 1 << 15;
-
-        /********************************/
-        /* HINTING FOR BGR?             */
-        /* Selector Bit:  9             */
-        /* Return Bit(s): 16            */
-        /*                              */
-        /* Functionality still needs to be added */
-        if ( ( args[0] & 512 ) != 0 && exc->bgr )
-          K |= 1 << 16;
-
-        if ( exc->rasterizer_version >= 38 )
-        {
-          /********************************/
-          /* SUBPIXEL POSITIONED?         */
-          /* Selector Bit:  10            */
-          /* Return Bit(s): 17            */
-          /*                              */
-          /* Functionality still needs to be added */
-          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;
-        }
-      }
-    }
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    args[0] = K;
-  }
-
-
-  static void
-  Ins_UNKNOWN( TT_ExecContext  exc )
-  {
-    TT_DefRecord*  def   = exc->IDefs;
-    TT_DefRecord*  limit = def + exc->numIDefs;
-
-
-    for ( ; def < limit; def++ )
-    {
-      if ( (FT_Byte)def->opc == exc->opcode && def->active )
-      {
-        TT_CallRec*  call;
-
-
-        if ( exc->callTop >= exc->callSize )
-        {
-          exc->error = FT_THROW( Stack_Overflow );
-          return;
-        }
-
-        call = exc->callStack + exc->callTop++;
-
-        call->Caller_Range = exc->curRange;
-        call->Caller_IP    = exc->IP + 1;
-        call->Cur_Count    = 1;
-        call->Def          = def;
-
-        Ins_Goto_CodeRange( exc, def->range, def->start );
-
-        exc->step_ins = FALSE;
-        return;
-      }
-    }
-
-    exc->error = FT_THROW( Invalid_Opcode );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RUN                                                                   */
-  /*                                                                       */
-  /*  This function executes a run of opcodes.  It will exit in the        */
-  /*  following cases:                                                     */
-  /*                                                                       */
-  /*  - Errors (in which case it returns FALSE).                           */
-  /*                                                                       */
-  /*  - Reaching the end of the main code range (returns TRUE).            */
-  /*    Reaching the end of a code range within a function call is an      */
-  /*    error.                                                             */
-  /*                                                                       */
-  /*  - After executing one single opcode, if the flag `Instruction_Trap'  */
-  /*    is set to TRUE (returns TRUE).                                     */
-  /*                                                                       */
-  /*  On exit with TRUE, test IP < CodeSize to know whether it comes from  */
-  /*  an instruction trap or a normal termination.                         */
-  /*                                                                       */
-  /*                                                                       */
-  /*  Note: The documented DEBUG opcode pops a value from the stack.  This */
-  /*        behaviour is unsupported; here a DEBUG opcode is always an     */
-  /*        error.                                                         */
-  /*                                                                       */
-  /*                                                                       */
-  /* THIS IS THE INTERPRETER'S MAIN LOOP.                                  */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /* documentation is in ttinterp.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  TT_RunIns( TT_ExecContext  exc )
-  {
-    FT_Long    ins_counter = 0;  /* executed instructions counter */
-    FT_UShort  i;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_Byte    opcode_pattern[1][2] = {
-                  /* #8 TypeMan Talk Align */
-                  {
-                    0x06, /* SPVTL   */
-                    0x7D, /* RDTG    */
-                  },
-                };
-    FT_UShort  opcode_patterns   = 1;
-    FT_UShort  opcode_pointer[1] = { 0 };
-    FT_UShort  opcode_size[1]    = { 1 };
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    exc->iup_called = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    /* set PPEM and CVT functions */
-    exc->tt_metrics.ratio = 0;
-    if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
-    {
-      /* non-square pixels, use the stretched routines */
-      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 */
-      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( exc );
-    Compute_Round( exc, (FT_Byte)exc->GS.round_state );
-
-    do
-    {
-      exc->opcode = exc->code[exc->IP];
-
-#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 = 1; n <= cnt; n++ )
-          FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
-        FT_TRACE6(( "\n" ));
-      }
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
-      if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
-      {
-        if ( exc->IP + 1 >= exc->codeSize )
-          goto LErrorCodeOverflow_;
-
-        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
-      }
-
-      if ( exc->IP + exc->length > exc->codeSize )
-        goto LErrorCodeOverflow_;
-
-      /* First, let's check for empty stack and overflow */
-      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 ( exc->args < 0 )
-      {
-        if ( exc->pedantic_hinting )
-        {
-          exc->error = FT_THROW( Too_Few_Arguments );
-          goto LErrorLabel_;
-        }
-
-        /* push zeroes onto the stack */
-        for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
-          exc->stack[i] = 0;
-        exc->args = 0;
-      }
-
-      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 ( exc->new_top > exc->stackSize )
-      {
-        exc->error = FT_THROW( Stack_Overflow );
-        goto LErrorLabel_;
-      }
-
-      exc->step_ins = TRUE;
-      exc->error    = FT_Err_Ok;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-      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: opcode ptrn: %d, %s %s\n",
-                          i,
-                          exc->face->root.family_name,
-                          exc->face->root.style_name ));
-
-              switch ( i )
-              {
-              case 0:
-                break;
-              }
-              opcode_pointer[i] = 0;
-            }
-          }
-          else
-            opcode_pointer[i] = 0;
-        }
-      }
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-      {
-        FT_Long*  args   = exc->stack + exc->args;
-        FT_Byte   opcode = exc->opcode;
-
-
-        switch ( opcode )
-        {
-        case 0x00:  /* SVTCA y  */
-        case 0x01:  /* SVTCA x  */
-        case 0x02:  /* SPvTCA y */
-        case 0x03:  /* SPvTCA x */
-        case 0x04:  /* SFvTCA y */
-        case 0x05:  /* SFvTCA x */
-          Ins_SxyTCA( exc );
-          break;
-
-        case 0x06:  /* SPvTL // */
-        case 0x07:  /* SPvTL +  */
-          Ins_SPVTL( exc, args );
-          break;
-
-        case 0x08:  /* SFvTL // */
-        case 0x09:  /* SFvTL +  */
-          Ins_SFVTL( exc, args );
-          break;
-
-        case 0x0A:  /* SPvFS */
-          Ins_SPVFS( exc, args );
-          break;
-
-        case 0x0B:  /* SFvFS */
-          Ins_SFVFS( exc, args );
-          break;
-
-        case 0x0C:  /* GPv */
-          Ins_GPV( exc, args );
-          break;
-
-        case 0x0D:  /* GFv */
-          Ins_GFV( exc, args );
-          break;
-
-        case 0x0E:  /* SFvTPv */
-          Ins_SFVTPV( exc );
-          break;
-
-        case 0x0F:  /* ISECT  */
-          Ins_ISECT( exc, args );
-          break;
-
-        case 0x10:  /* SRP0 */
-          Ins_SRP0( exc, args );
-          break;
-
-        case 0x11:  /* SRP1 */
-          Ins_SRP1( exc, args );
-          break;
-
-        case 0x12:  /* SRP2 */
-          Ins_SRP2( exc, args );
-          break;
-
-        case 0x13:  /* SZP0 */
-          Ins_SZP0( exc, args );
-          break;
-
-        case 0x14:  /* SZP1 */
-          Ins_SZP1( exc, args );
-          break;
-
-        case 0x15:  /* SZP2 */
-          Ins_SZP2( exc, args );
-          break;
-
-        case 0x16:  /* SZPS */
-          Ins_SZPS( exc, args );
-          break;
-
-        case 0x17:  /* SLOOP */
-          Ins_SLOOP( exc, args );
-          break;
-
-        case 0x18:  /* RTG */
-          Ins_RTG( exc );
-          break;
-
-        case 0x19:  /* RTHG */
-          Ins_RTHG( exc );
-          break;
-
-        case 0x1A:  /* SMD */
-          Ins_SMD( exc, args );
-          break;
-
-        case 0x1B:  /* ELSE */
-          Ins_ELSE( exc );
-          break;
-
-        case 0x1C:  /* JMPR */
-          Ins_JMPR( exc, args );
-          break;
-
-        case 0x1D:  /* SCVTCI */
-          Ins_SCVTCI( exc, args );
-          break;
-
-        case 0x1E:  /* SSWCI */
-          Ins_SSWCI( exc, args );
-          break;
-
-        case 0x1F:  /* SSW */
-          Ins_SSW( exc, args );
-          break;
-
-        case 0x20:  /* DUP */
-          Ins_DUP( args );
-          break;
-
-        case 0x21:  /* POP */
-          Ins_POP();
-          break;
-
-        case 0x22:  /* CLEAR */
-          Ins_CLEAR( exc );
-          break;
-
-        case 0x23:  /* SWAP */
-          Ins_SWAP( args );
-          break;
-
-        case 0x24:  /* DEPTH */
-          Ins_DEPTH( exc, args );
-          break;
-
-        case 0x25:  /* CINDEX */
-          Ins_CINDEX( exc, args );
-          break;
-
-        case 0x26:  /* MINDEX */
-          Ins_MINDEX( exc, args );
-          break;
-
-        case 0x27:  /* ALIGNPTS */
-          Ins_ALIGNPTS( exc, args );
-          break;
-
-        case 0x28:  /* ???? */
-          Ins_UNKNOWN( exc );
-          break;
-
-        case 0x29:  /* UTP */
-          Ins_UTP( exc, args );
-          break;
-
-        case 0x2A:  /* LOOPCALL */
-          Ins_LOOPCALL( exc, args );
-          break;
-
-        case 0x2B:  /* CALL */
-          Ins_CALL( exc, args );
-          break;
-
-        case 0x2C:  /* FDEF */
-          Ins_FDEF( exc, args );
-          break;
-
-        case 0x2D:  /* ENDF */
-          Ins_ENDF( exc );
-          break;
-
-        case 0x2E:  /* MDAP */
-        case 0x2F:  /* MDAP */
-          Ins_MDAP( exc, args );
-          break;
-
-        case 0x30:  /* IUP */
-        case 0x31:  /* IUP */
-          Ins_IUP( exc );
-          break;
-
-        case 0x32:  /* SHP */
-        case 0x33:  /* SHP */
-          Ins_SHP( exc );
-          break;
-
-        case 0x34:  /* SHC */
-        case 0x35:  /* SHC */
-          Ins_SHC( exc, args );
-          break;
-
-        case 0x36:  /* SHZ */
-        case 0x37:  /* SHZ */
-          Ins_SHZ( exc, args );
-          break;
-
-        case 0x38:  /* SHPIX */
-          Ins_SHPIX( exc, args );
-          break;
-
-        case 0x39:  /* IP    */
-          Ins_IP( exc );
-          break;
-
-        case 0x3A:  /* MSIRP */
-        case 0x3B:  /* MSIRP */
-          Ins_MSIRP( exc, args );
-          break;
-
-        case 0x3C:  /* AlignRP */
-          Ins_ALIGNRP( exc );
-          break;
-
-        case 0x3D:  /* RTDG */
-          Ins_RTDG( exc );
-          break;
-
-        case 0x3E:  /* MIAP */
-        case 0x3F:  /* MIAP */
-          Ins_MIAP( exc, args );
-          break;
-
-        case 0x40:  /* NPUSHB */
-          Ins_NPUSHB( exc, args );
-          break;
-
-        case 0x41:  /* NPUSHW */
-          Ins_NPUSHW( exc, args );
-          break;
-
-        case 0x42:  /* WS */
-          Ins_WS( exc, args );
-          break;
-
-        case 0x43:  /* RS */
-          Ins_RS( exc, args );
-          break;
-
-        case 0x44:  /* WCVTP */
-          Ins_WCVTP( exc, args );
-          break;
-
-        case 0x45:  /* RCVT */
-          Ins_RCVT( exc, args );
-          break;
-
-        case 0x46:  /* GC */
-        case 0x47:  /* GC */
-          Ins_GC( exc, args );
-          break;
-
-        case 0x48:  /* SCFS */
-          Ins_SCFS( exc, args );
-          break;
-
-        case 0x49:  /* MD */
-        case 0x4A:  /* MD */
-          Ins_MD( exc, args );
-          break;
-
-        case 0x4B:  /* MPPEM */
-          Ins_MPPEM( exc, args );
-          break;
-
-        case 0x4C:  /* MPS */
-          Ins_MPS( exc, args );
-          break;
-
-        case 0x4D:  /* FLIPON */
-          Ins_FLIPON( exc );
-          break;
-
-        case 0x4E:  /* FLIPOFF */
-          Ins_FLIPOFF( exc );
-          break;
-
-        case 0x4F:  /* DEBUG */
-          Ins_DEBUG( exc );
-          break;
-
-        case 0x50:  /* LT */
-          Ins_LT( args );
-          break;
-
-        case 0x51:  /* LTEQ */
-          Ins_LTEQ( args );
-          break;
-
-        case 0x52:  /* GT */
-          Ins_GT( args );
-          break;
-
-        case 0x53:  /* GTEQ */
-          Ins_GTEQ( args );
-          break;
-
-        case 0x54:  /* EQ */
-          Ins_EQ( args );
-          break;
-
-        case 0x55:  /* NEQ */
-          Ins_NEQ( args );
-          break;
-
-        case 0x56:  /* ODD */
-          Ins_ODD( exc, args );
-          break;
-
-        case 0x57:  /* EVEN */
-          Ins_EVEN( exc, args );
-          break;
-
-        case 0x58:  /* IF */
-          Ins_IF( exc, args );
-          break;
-
-        case 0x59:  /* EIF */
-          Ins_EIF();
-          break;
-
-        case 0x5A:  /* AND */
-          Ins_AND( args );
-          break;
-
-        case 0x5B:  /* OR */
-          Ins_OR( args );
-          break;
-
-        case 0x5C:  /* NOT */
-          Ins_NOT( args );
-          break;
-
-        case 0x5D:  /* DELTAP1 */
-          Ins_DELTAP( exc, args );
-          break;
-
-        case 0x5E:  /* SDB */
-          Ins_SDB( exc, args );
-          break;
-
-        case 0x5F:  /* SDS */
-          Ins_SDS( exc, args );
-          break;
-
-        case 0x60:  /* ADD */
-          Ins_ADD( args );
-          break;
-
-        case 0x61:  /* SUB */
-          Ins_SUB( args );
-          break;
-
-        case 0x62:  /* DIV */
-          Ins_DIV( exc, args );
-          break;
-
-        case 0x63:  /* MUL */
-          Ins_MUL( args );
-          break;
-
-        case 0x64:  /* ABS */
-          Ins_ABS( args );
-          break;
-
-        case 0x65:  /* NEG */
-          Ins_NEG( args );
-          break;
-
-        case 0x66:  /* FLOOR */
-          Ins_FLOOR( args );
-          break;
-
-        case 0x67:  /* CEILING */
-          Ins_CEILING( args );
-          break;
-
-        case 0x68:  /* ROUND */
-        case 0x69:  /* ROUND */
-        case 0x6A:  /* ROUND */
-        case 0x6B:  /* ROUND */
-          Ins_ROUND( exc, args );
-          break;
-
-        case 0x6C:  /* NROUND */
-        case 0x6D:  /* NROUND */
-        case 0x6E:  /* NRRUND */
-        case 0x6F:  /* NROUND */
-          Ins_NROUND( exc, args );
-          break;
-
-        case 0x70:  /* WCVTF */
-          Ins_WCVTF( exc, args );
-          break;
-
-        case 0x71:  /* DELTAP2 */
-        case 0x72:  /* DELTAP3 */
-          Ins_DELTAP( exc, args );
-          break;
-
-        case 0x73:  /* DELTAC0 */
-        case 0x74:  /* DELTAC1 */
-        case 0x75:  /* DELTAC2 */
-          Ins_DELTAC( exc, args );
-          break;
-
-        case 0x76:  /* SROUND */
-          Ins_SROUND( exc, args );
-          break;
-
-        case 0x77:  /* S45Round */
-          Ins_S45ROUND( exc, args );
-          break;
-
-        case 0x78:  /* JROT */
-          Ins_JROT( exc, args );
-          break;
-
-        case 0x79:  /* JROF */
-          Ins_JROF( exc, args );
-          break;
-
-        case 0x7A:  /* ROFF */
-          Ins_ROFF( exc );
-          break;
-
-        case 0x7B:  /* ???? */
-          Ins_UNKNOWN( exc );
-          break;
-
-        case 0x7C:  /* RUTG */
-          Ins_RUTG( exc );
-          break;
-
-        case 0x7D:  /* RDTG */
-          Ins_RDTG( exc );
-          break;
-
-        case 0x7E:  /* SANGW */
-          Ins_SANGW();
-          break;
-
-        case 0x7F:  /* AA */
-          Ins_AA();
-          break;
-
-        case 0x80:  /* FLIPPT */
-          Ins_FLIPPT( exc );
-          break;
-
-        case 0x81:  /* FLIPRGON */
-          Ins_FLIPRGON( exc, args );
-          break;
-
-        case 0x82:  /* FLIPRGOFF */
-          Ins_FLIPRGOFF( exc, args );
-          break;
-
-        case 0x83:  /* UNKNOWN */
-        case 0x84:  /* UNKNOWN */
-          Ins_UNKNOWN( exc );
-          break;
-
-        case 0x85:  /* SCANCTRL */
-          Ins_SCANCTRL( exc, args );
-          break;
-
-        case 0x86:  /* SDPvTL */
-        case 0x87:  /* SDPvTL */
-          Ins_SDPVTL( exc, args );
-          break;
-
-        case 0x88:  /* GETINFO */
-          Ins_GETINFO( exc, args );
-          break;
-
-        case 0x89:  /* IDEF */
-          Ins_IDEF( exc, args );
-          break;
-
-        case 0x8A:  /* ROLL */
-          Ins_ROLL( args );
-          break;
-
-        case 0x8B:  /* MAX */
-          Ins_MAX( args );
-          break;
-
-        case 0x8C:  /* MIN */
-          Ins_MIN( args );
-          break;
-
-        case 0x8D:  /* SCANTYPE */
-          Ins_SCANTYPE( exc, args );
-          break;
-
-        case 0x8E:  /* INSTCTRL */
-          Ins_INSTCTRL( exc, args );
-          break;
-
-        case 0x8F:
-          Ins_UNKNOWN( exc );
-          break;
-
-        default:
-          if ( opcode >= 0xE0 )
-            Ins_MIRP( exc, args );
-          else if ( opcode >= 0xC0 )
-            Ins_MDRP( exc, args );
-          else if ( opcode >= 0xB8 )
-            Ins_PUSHW( exc, args );
-          else if ( opcode >= 0xB0 )
-            Ins_PUSHB( exc, args );
-          else
-            Ins_UNKNOWN( exc );
-        }
-      }
-
-      if ( exc->error )
-      {
-        switch ( exc->error )
-        {
-          /* looking for redefined instructions */
-        case FT_ERR( Invalid_Opcode ):
-          {
-            TT_DefRecord*  def   = exc->IDefs;
-            TT_DefRecord*  limit = def + exc->numIDefs;
-
-
-            for ( ; def < limit; def++ )
-            {
-              if ( def->active && exc->opcode == (FT_Byte)def->opc )
-              {
-                TT_CallRec*  callrec;
-
-
-                if ( exc->callTop >= exc->callSize )
-                {
-                  exc->error = FT_THROW( Invalid_Reference );
-                  goto LErrorLabel_;
-                }
-
-                callrec = &exc->callStack[exc->callTop];
-
-                callrec->Caller_Range = exc->curRange;
-                callrec->Caller_IP    = exc->IP + 1;
-                callrec->Cur_Count    = 1;
-                callrec->Def          = def;
-
-                if ( Ins_Goto_CodeRange( exc,
-                                         def->range,
-                                         def->start ) == FAILURE )
-                  goto LErrorLabel_;
-
-                goto LSuiteLabel_;
-              }
-            }
-          }
-
-          exc->error = FT_THROW( Invalid_Opcode );
-          goto LErrorLabel_;
-
-#if 0
-          break;   /* Unreachable code warning suppression.             */
-                   /* Leave to remind in case a later change the editor */
-                   /* to consider break;                                */
-#endif
-
-        default:
-          goto LErrorLabel_;
-
-#if 0
-        break;
-#endif
-        }
-      }
-
-      exc->top = exc->new_top;
-
-      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). */
-      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
-        return FT_THROW( Execution_Too_Long );
-
-    LSuiteLabel_:
-      if ( exc->IP >= exc->codeSize )
-      {
-        if ( exc->callTop > 0 )
-        {
-          exc->error = FT_THROW( Code_Overflow );
-          goto LErrorLabel_;
-        }
-        else
-          goto LNo_Error_;
-      }
-    } while ( !exc->instruction_trap );
-
-  LNo_Error_:
-    return FT_Err_Ok;
-
-  LErrorCodeOverflow_:
-    exc->error = FT_THROW( Code_Overflow );
-
-  LErrorLabel_:
-    /* 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 ( exc->error                          &&
-         !exc->instruction_trap              &&
-         exc->curRange == tt_coderange_glyph )
-    {
-      FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
-      exc->size->bytecode_ready = -1;
-      exc->size->cvt_ready      = -1;
-    }
-
-    return exc->error;
-  }
-
-
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
-
-/* END */