godot/thirdparty/freetype/src/truetype/ttinterp.c

/****************************************************************************
 *
 * ttinterp.c
 *
 *   TrueType bytecode interpreter (body).
 *
 * Copyright (C) 1996-2023 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 <freetype/internal/ftdebug.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/fttrigon.h>
#include <freetype/ftsystem.h>
#include <freetype/ftdriver.h>
#include <freetype/ftmm.h>

#include "ttinterp.h"
#include "tterrors.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h"
#endif


#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


#define NO_SUBPIXEL_HINTING

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
#define SUBPIXEL_HINTING_MINIMAL
#endif

#define PROJECT( v1, v2 )

#define DUALPROJ( v1, v2 )

#define FAST_PROJECT( v )

#define FAST_DUALPROJ( v )


  /**************************************************************************
   *
   * Two simple bounds-checking macros.
   */
#define BOUNDS( x, n )
#define BOUNDSL( x, n )


#undef  SUCCESS
#define SUCCESS

#undef  FAILURE
#define FAILURE


  /**************************************************************************
   *
   *                       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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   *                  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 )
  {}


  /**************************************************************************
   *
   * @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.
   *
   *   Note that not all members of `TT_ExecContext` get initialized.
   */
  FT_LOCAL_DEF( FT_Error )
  TT_Load_Context( TT_ExecContext  exec,
                   TT_Face         face,
                   TT_Size         size )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @Function:
   *   TT_Run_Context
   *
   * @Description:
   *   Executes one or more instructions in the execution context.
   *
   * @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 )
  {}


  /* 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 =;


  /* documentation is in ttinterp.h */

  FT_EXPORT_DEF( TT_ExecContext )
  TT_New_Context( TT_Driver  driver )
  {}


  /**************************************************************************
   *
   * 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


  static
  const FT_Byte  Pop_Push_Count[256] =;


#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] =
  {
    /* 0x00 */
    "8 SVTCA[y]",
    "8 SVTCA[x]",
    "9 SPVTCA[y]",
    "9 SPVTCA[x]",
    "9 SFVTCA[y]",
    "9 SFVTCA[x]",
    "9 SPVTL[||]",
    "8 SPVTL[+]",
    "9 SFVTL[||]",
    "8 SFVTL[+]",
    "5 SPVFS",
    "5 SFVFS",
    "3 GPV",
    "3 GFV",
    "6 SFVTPV",
    "5 ISECT",

    /* 0x10 */
    "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",

    /* 0x20 */
    "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",
    "6 MDAP[]",
    "9 MDAP[rnd]",

    /* 0x30 */
    "6 IUP[y]",
    "6 IUP[x]",
    "8 SHP[rp2]",
    "8 SHP[rp1]",
    "8 SHC[rp2]",
    "8 SHC[rp1]",
    "8 SHZ[rp2]",
    "8 SHZ[rp1]",
    "5 SHPIX",
    "2 IP",
    "7 MSIRP[]",
    "A MSIRP[rp0]",
    "7 ALIGNRP",
    "4 RTDG",
    "6 MIAP[]",
    "9 MIAP[rnd]",

    /* 0x40 */
    "6 NPUSHB",
    "6 NPUSHW",
    "2 WS",
    "2 RS",
    "5 WCVTP",
    "4 RCVT",
    "8 GC[curr]",
    "8 GC[orig]",
    "4 SCFS",
    "8 MD[curr]",
    "8 MD[orig]",
    "5 MPPEM",
    "3 MPS",
    "6 FLIPON",
    "7 FLIPOFF",
    "5 DEBUG",

    /* 0x50 */
    "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",

    /* 0x60 */
    "3 ADD",
    "3 SUB",
    "3 DIV",
    "3 MUL",
    "3 ABS",
    "3 NEG",
    "5 FLOOR",
    "7 CEILING",
    "8 ROUND[G]",
    "8 ROUND[B]",
    "8 ROUND[W]",
    "7 ROUND[]",
    "9 NROUND[G]",
    "9 NROUND[B]",
    "9 NROUND[W]",
    "8 NROUND[]",

    /* 0x70 */
    "5 WCVTF",
    "7 DELTAP2",
    "7 DELTAP3",
    "7 DELTAC1",
    "7 DELTAC2",
    "7 DELTAC3",
    "6 SROUND",
    "8 S45ROUND",
    "4 JROT",
    "4 JROF",
    "4 ROFF",
    "7 INS_$7B",
    "4 RUTG",
    "4 RDTG",
    "5 SANGW",
    "2 AA",

    /* 0x80 */
    "6 FLIPPT",
    "8 FLIPRGON",
    "9 FLIPRGOFF",
    "7 INS_$83",
    "7 INS_$84",
    "8 SCANCTRL",
    "A SDPVTL[||]",
    "9 SDPVTL[+]",
    "7 GETINFO",
    "4 IDEF",
    "4 ROLL",
    "3 MAX",
    "3 MIN",
    "8 SCANTYPE",
    "8 INSTCTRL",
    "7 INS_$8F",

    /* 0x90 */
    "7 INS_$90",
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    "C GETVARIATION",
    "7 GETDATA",
#else
    "7 INS_$91",
    "7 INS_$92",
#endif
    "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",

    /* 0xA0 */
    "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",

    /* 0xB0 */
    "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]",

    /* 0xC0 */
    "7 MDRP[G]",
    "7 MDRP[B]",
    "7 MDRP[W]",
    "6 MDRP[]",
    "8 MDRP[rG]",
    "8 MDRP[rB]",
    "8 MDRP[rW]",
    "7 MDRP[r]",
    "8 MDRP[mG]",
    "8 MDRP[mB]",
    "8 MDRP[mW]",
    "7 MDRP[m]",
    "9 MDRP[mrG]",
    "9 MDRP[mrB]",
    "9 MDRP[mrW]",
    "8 MDRP[mr]",

    /* 0xD0 */
    "8 MDRP[pG]",
    "8 MDRP[pB]",
    "8 MDRP[pW]",
    "7 MDRP[p]",
    "9 MDRP[prG]",
    "9 MDRP[prB]",
    "9 MDRP[prW]",
    "8 MDRP[pr]",
    "9 MDRP[pmG]",
    "9 MDRP[pmB]",
    "9 MDRP[pmW]",
    "8 MDRP[pm]",
    "A MDRP[pmrG]",
    "A MDRP[pmrB]",
    "A MDRP[pmrW]",
    "9 MDRP[pmr]",

    /* 0xE0 */
    "7 MIRP[G]",
    "7 MIRP[B]",
    "7 MIRP[W]",
    "6 MIRP[]",
    "8 MIRP[rG]",
    "8 MIRP[rB]",
    "8 MIRP[rW]",
    "7 MIRP[r]",
    "8 MIRP[mG]",
    "8 MIRP[mB]",
    "8 MIRP[mW]",
    "7 MIRP[m]",
    "9 MIRP[mrG]",
    "9 MIRP[mrB]",
    "9 MIRP[mrW]",
    "8 MIRP[mr]",

    /* 0xF0 */
    "8 MIRP[pG]",
    "8 MIRP[pB]",
    "8 MIRP[pW]",
    "7 MIRP[p]",
    "9 MIRP[prG]",
    "9 MIRP[prB]",
    "9 MIRP[prW]",
    "8 MIRP[pr]",
    "9 MIRP[pmG]",
    "9 MIRP[pmB]",
    "9 MIRP[pmW]",
    "8 MIRP[pm]",
    "A MIRP[pmrG]",
    "A MIRP[pmrB]",
    "A MIRP[pmrW]",
    "9 MIRP[pmr]"
  };

#endif /* FT_DEBUG_LEVEL_TRACE */


  static
  const FT_Char  opcode_length[256] =;

#undef PACK


#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER

#if defined( __arm__ )                                 && \
    ( defined( __thumb2__ ) || !defined( __thumb__ ) )

#define TT_MulFix14

  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

  /* 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 )
  {}

#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

#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 )
  {}

#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 )
  {}


  FT_CALLBACK_DEF( FT_Long )
  Current_Ppem( TT_ExecContext  exc )
  {}


  FT_CALLBACK_DEF( FT_Long )
  Current_Ppem_Stretched( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * Functions related to the control value table (CVT).
   *
   */


  FT_CALLBACK_DEF( FT_F26Dot6 )
  Read_CVT( TT_ExecContext  exc,
            FT_ULong        idx )
  {}


  FT_CALLBACK_DEF( FT_F26Dot6 )
  Read_CVT_Stretched( TT_ExecContext  exc,
                      FT_ULong        idx )
  {}


  static void
  Modify_CVT_Check( TT_ExecContext  exc )
  {}


  FT_CALLBACK_DEF( void )
  Write_CVT( TT_ExecContext  exc,
             FT_ULong        idx,
             FT_F26Dot6      value )
  {}


  FT_CALLBACK_DEF( void )
  Write_CVT_Stretched( TT_ExecContext  exc,
                       FT_ULong        idx,
                       FT_F26Dot6      value )
  {}


  FT_CALLBACK_DEF( void )
  Move_CVT( TT_ExecContext  exc,
            FT_ULong        idx,
            FT_F26Dot6      value )
  {}


  FT_CALLBACK_DEF( void )
  Move_CVT_Stretched( TT_ExecContext  exc,
                      FT_ULong        idx,
                      FT_F26Dot6      value )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /*
   *
   * Apple's TrueType specification at
   *
   *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#order
   *
   * gives the following order of operations in instructions that move
   * points.
   *
   *   - check single width cut-in (MIRP, MDRP)
   *
   *   - check control value cut-in (MIRP, MIAP)
   *
   *   - apply engine compensation (MIRP, MDRP)
   *
   *   - round distance (MIRP, MDRP) or value (MIAP, MDAP)
   *
   *   - check minimum distance (MIRP,MDRP)
   *
   *   - move point (MIRP, MDRP, MIAP, MSIRP, MDAP)
   *
   * For rounding instructions, engine compensation happens before rounding.
   *
   */


  /**************************************************************************
   *
   * @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.
   *
   * @Note:
   *   See `ttinterp.h' for details on backward compatibility mode.
   *   `Touches' the point.
   */
  static void
  Direct_Move( TT_ExecContext  exc,
               TT_GlyphZone    zone,
               FT_UShort       point,
               FT_F26Dot6      distance )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * 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.
   *   See `ttinterp.h' for details on backward compatibility mode.
   *
   */


  static void
  Direct_Move_X( TT_ExecContext  exc,
                 TT_GlyphZone    zone,
                 FT_UShort       point,
                 FT_F26Dot6      distance )
  {}


  static void
  Direct_Move_Y( TT_ExecContext  exc,
                 TT_GlyphZone    zone,
                 FT_UShort       point,
                 FT_F26Dot6      distance )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  static void
  Direct_Move_Orig_Y( TT_ExecContext  exc,
                      TT_GlyphZone    zone,
                      FT_UShort       point,
                      FT_F26Dot6      distance )
  {}

  /**************************************************************************
   *
   * @Function:
   *   Round_None
   *
   * @Description:
   *   Does not round, but adds engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance (not) to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   The compensated distance.
   */
  static FT_F26Dot6
  Round_None( TT_ExecContext  exc,
              FT_F26Dot6      distance,
              FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_To_Grid
   *
   * @Description:
   *   Rounds value to grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   */
  static FT_F26Dot6
  Round_To_Grid( TT_ExecContext  exc,
                 FT_F26Dot6      distance,
                 FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_To_Half_Grid
   *
   * @Description:
   *   Rounds value to half grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   */
  static FT_F26Dot6
  Round_To_Half_Grid( TT_ExecContext  exc,
                      FT_F26Dot6      distance,
                      FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_Down_To_Grid
   *
   * @Description:
   *   Rounds value down to grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   */
  static FT_F26Dot6
  Round_Down_To_Grid( TT_ExecContext  exc,
                      FT_F26Dot6      distance,
                      FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_Up_To_Grid
   *
   * @Description:
   *   Rounds value up to grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   */
  static FT_F26Dot6
  Round_Up_To_Grid( TT_ExecContext  exc,
                    FT_F26Dot6      distance,
                    FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_To_Double_Grid
   *
   * @Description:
   *   Rounds value to double grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   */
  static FT_F26Dot6
  Round_To_Double_Grid( TT_ExecContext  exc,
                        FT_F26Dot6      distance,
                        FT_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_Super
   *
   * @Description:
   *   Super-rounds value to grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @Return:
   *   Rounded distance.
   *
   * @Note:
   *   The TrueType specification says very little 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_Int          color )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Round_Super_45
   *
   * @Description:
   *   Super-rounds value to grid after adding engine compensation.
   *
   * @Input:
   *   distance ::
   *     The distance to round.
   *
   *   color ::
   *     The engine compensation color.
   *
   * @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_Int          color )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * @Function:
   *   Compute_Funcs
   *
   * @Description:
   *   Computes the projection and movement function pointers according
   *   to the current graphics state.
   */
  static void
  Compute_Funcs( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * @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 )
  {}


  /**************************************************************************
   *
   * Here we start with the implementation of the various opcodes.
   *
   */


#define ARRAY_BOUND_ERROR


  /**************************************************************************
   *
   * MPPEM[]:      Measure Pixel Per EM
   * Opcode range: 0x4B
   * Stack:        --> Euint16
   */
  static void
  Ins_MPPEM( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MPS[]:        Measure Point Size
   * Opcode range: 0x4C
   * Stack:        --> Euint16
   */
  static void
  Ins_MPS( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * DUP[]:        DUPlicate the stack's top element
   * Opcode range: 0x20
   * Stack:        StkElt --> StkElt StkElt
   */
  static void
  Ins_DUP( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * POP[]:        POP the stack's top element
   * Opcode range: 0x21
   * Stack:        StkElt -->
   */
  static void
  Ins_POP( void )
  {}


  /**************************************************************************
   *
   * CLEAR[]:      CLEAR the entire stack
   * Opcode range: 0x22
   * Stack:        StkElt... -->
   */
  static void
  Ins_CLEAR( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * SWAP[]:       SWAP the stack's top two elements
   * Opcode range: 0x23
   * Stack:        2 * StkElt --> 2 * StkElt
   */
  static void
  Ins_SWAP( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * DEPTH[]:      return the stack DEPTH
   * Opcode range: 0x24
   * Stack:        --> uint32
   */
  static void
  Ins_DEPTH( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * LT[]:         Less Than
   * Opcode range: 0x50
   * Stack:        int32? int32? --> bool
   */
  static void
  Ins_LT( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * LTEQ[]:       Less Than or EQual
   * Opcode range: 0x51
   * Stack:        int32? int32? --> bool
   */
  static void
  Ins_LTEQ( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * GT[]:         Greater Than
   * Opcode range: 0x52
   * Stack:        int32? int32? --> bool
   */
  static void
  Ins_GT( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * GTEQ[]:       Greater Than or EQual
   * Opcode range: 0x53
   * Stack:        int32? int32? --> bool
   */
  static void
  Ins_GTEQ( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * EQ[]:         EQual
   * Opcode range: 0x54
   * Stack:        StkElt StkElt --> bool
   */
  static void
  Ins_EQ( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * NEQ[]:        Not EQual
   * Opcode range: 0x55
   * Stack:        StkElt StkElt --> bool
   */
  static void
  Ins_NEQ( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * ODD[]:        Is ODD
   * Opcode range: 0x56
   * Stack:        f26.6 --> bool
   */
  static void
  Ins_ODD( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * EVEN[]:       Is EVEN
   * Opcode range: 0x57
   * Stack:        f26.6 --> bool
   */
  static void
  Ins_EVEN( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * AND[]:        logical AND
   * Opcode range: 0x5A
   * Stack:        uint32 uint32 --> uint32
   */
  static void
  Ins_AND( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * OR[]:         logical OR
   * Opcode range: 0x5B
   * Stack:        uint32 uint32 --> uint32
   */
  static void
  Ins_OR( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * NOT[]:        logical NOT
   * Opcode range: 0x5C
   * Stack:        StkElt --> uint32
   */
  static void
  Ins_NOT( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * ADD[]:        ADD
   * Opcode range: 0x60
   * Stack:        f26.6 f26.6 --> f26.6
   */
  static void
  Ins_ADD( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * SUB[]:        SUBtract
   * Opcode range: 0x61
   * Stack:        f26.6 f26.6 --> f26.6
   */
  static void
  Ins_SUB( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * DIV[]:        DIVide
   * Opcode range: 0x62
   * Stack:        f26.6 f26.6 --> f26.6
   */
  static void
  Ins_DIV( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MUL[]:        MULtiply
   * Opcode range: 0x63
   * Stack:        f26.6 f26.6 --> f26.6
   */
  static void
  Ins_MUL( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * ABS[]:        ABSolute value
   * Opcode range: 0x64
   * Stack:        f26.6 --> f26.6
   */
  static void
  Ins_ABS( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * NEG[]:        NEGate
   * Opcode range: 0x65
   * Stack:        f26.6 --> f26.6
   */
  static void
  Ins_NEG( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * FLOOR[]:      FLOOR
   * Opcode range: 0x66
   * Stack:        f26.6 --> f26.6
   */
  static void
  Ins_FLOOR( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * CEILING[]:    CEILING
   * Opcode range: 0x67
   * Stack:        f26.6 --> f26.6
   */
  static void
  Ins_CEILING( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * RS[]:         Read Store
   * Opcode range: 0x43
   * Stack:        uint32 --> uint32
   */
  static void
  Ins_RS( TT_ExecContext  exc,
          FT_Long*        args )
  {}


  /**************************************************************************
   *
   * WS[]:         Write Store
   * Opcode range: 0x42
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_WS( TT_ExecContext  exc,
          FT_Long*        args )
  {}


  /**************************************************************************
   *
   * WCVTP[]:      Write CVT in Pixel units
   * Opcode range: 0x44
   * Stack:        f26.6 uint32 -->
   */
  static void
  Ins_WCVTP( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * WCVTF[]:      Write CVT in Funits
   * Opcode range: 0x70
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_WCVTF( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * RCVT[]:       Read CVT
   * Opcode range: 0x45
   * Stack:        uint32 --> f26.6
   */
  static void
  Ins_RCVT( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * AA[]:         Adjust Angle
   * Opcode range: 0x7F
   * Stack:        uint32 -->
   */
  static void
  Ins_AA( void )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * ROUND[ab]:    ROUND value
   * Opcode range: 0x68-0x6B
   * Stack:        f26.6 --> f26.6
   */
  static void
  Ins_ROUND( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * MAX[]:        MAXimum
   * Opcode range: 0x8B
   * Stack:        int32? int32? --> int32
   */
  static void
  Ins_MAX( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * MIN[]:        MINimum
   * Opcode range: 0x8C
   * Stack:        int32? int32? --> int32
   */
  static void
  Ins_MIN( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * MINDEX[]:     Move INDEXed element
   * Opcode range: 0x26
   * Stack:        int32? --> StkElt
   */
  static void
  Ins_MINDEX( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * CINDEX[]:     Copy INDEXed element
   * Opcode range: 0x25
   * Stack:        int32 --> StkElt
   */
  static void
  Ins_CINDEX( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * ROLL[]:       ROLL top three elements
   * Opcode range: 0x8A
   * Stack:        3 * StkElt --> 3 * StkElt
   */
  static void
  Ins_ROLL( FT_Long*  args )
  {}


  /**************************************************************************
   *
   * MANAGING THE FLOW OF CONTROL
   *
   */


  /**************************************************************************
   *
   * SLOOP[]:      Set LOOP variable
   * Opcode range: 0x17
   * Stack:        int32? -->
   */
  static void
  Ins_SLOOP( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  static FT_Bool
  SkipCode( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * IF[]:         IF test
   * Opcode range: 0x58
   * Stack:        StkElt -->
   */
  static void
  Ins_IF( TT_ExecContext  exc,
          FT_Long*        args )
  {}


  /**************************************************************************
   *
   * ELSE[]:       ELSE
   * Opcode range: 0x1B
   * Stack:        -->
   */
  static void
  Ins_ELSE( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * EIF[]:        End IF
   * Opcode range: 0x59
   * Stack:        -->
   */
  static void
  Ins_EIF( void )
  {}


  /**************************************************************************
   *
   * JMPR[]:       JuMP Relative
   * Opcode range: 0x1C
   * Stack:        int32 -->
   */
  static void
  Ins_JMPR( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * JROT[]:       Jump Relative On True
   * Opcode range: 0x78
   * Stack:        StkElt int32 -->
   */
  static void
  Ins_JROT( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * JROF[]:       Jump Relative On False
   * Opcode range: 0x79
   * Stack:        StkElt int32 -->
   */
  static void
  Ins_JROF( TT_ExecContext  exc,
            FT_Long*        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 )
  {}


  /**************************************************************************
   *
   * ENDF[]:       END Function definition
   * Opcode range: 0x2D
   * Stack:        -->
   */
  static void
  Ins_ENDF( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * CALL[]:       CALL function
   * Opcode range: 0x2B
   * Stack:        uint32? -->
   */
  static void
  Ins_CALL( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * LOOPCALL[]:   LOOP and CALL function
   * Opcode range: 0x2A
   * Stack:        uint32? Eint16? -->
   */
  static void
  Ins_LOOPCALL( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * IDEF[]:       Instruction DEFinition
   * Opcode range: 0x89
   * Stack:        Eint8 -->
   */
  static void
  Ins_IDEF( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * NPUSHW[]:     PUSH N Words
   * Opcode range: 0x41
   * Stack:        --> int32...
   */
  static void
  Ins_NPUSHW( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * PUSHB[abc]:   PUSH Bytes
   * Opcode range: 0xB0-0xB7
   * Stack:        --> uint32...
   */
  static void
  Ins_PUSHB( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * PUSHW[abc]:   PUSH Words
   * Opcode range: 0xB8-0xBF
   * Stack:        --> int32...
   */
  static void
  Ins_PUSHW( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MANAGING THE GRAPHICS STATE
   *
   */


  static FT_Bool
  Ins_SxVTL( TT_ExecContext  exc,
             FT_UShort       aIdx1,
             FT_UShort       aIdx2,
             FT_UnitVector*  Vec )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * SPvTL[a]:     Set PVector To Line
   * Opcode range: 0x06-0x07
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_SPVTL( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SFvTL[a]:     Set FVector To Line
   * Opcode range: 0x08-0x09
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_SFVTL( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SFvTPv[]:     Set FVector To PVector
   * Opcode range: 0x0E
   * Stack:        -->
   */
  static void
  Ins_SFVTPV( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * SPvFS[]:      Set PVector From Stack
   * Opcode range: 0x0A
   * Stack:        f2.14 f2.14 -->
   */
  static void
  Ins_SPVFS( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SFvFS[]:      Set FVector From Stack
   * Opcode range: 0x0B
   * Stack:        f2.14 f2.14 -->
   */
  static void
  Ins_SFVFS( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * GPv[]:        Get Projection Vector
   * Opcode range: 0x0C
   * Stack:        ef2.14 --> ef2.14
   */
  static void
  Ins_GPV( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * GFv[]:        Get Freedom Vector
   * Opcode range: 0x0D
   * Stack:        ef2.14 --> ef2.14
   */
  static void
  Ins_GFV( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SRP0[]:       Set Reference Point 0
   * Opcode range: 0x10
   * Stack:        uint32 -->
   */
  static void
  Ins_SRP0( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SRP1[]:       Set Reference Point 1
   * Opcode range: 0x11
   * Stack:        uint32 -->
   */
  static void
  Ins_SRP1( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SRP2[]:       Set Reference Point 2
   * Opcode range: 0x12
   * Stack:        uint32 -->
   */
  static void
  Ins_SRP2( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SMD[]:        Set Minimum Distance
   * Opcode range: 0x1A
   * Stack:        f26.6 -->
   */
  static void
  Ins_SMD( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SCVTCI[]:     Set Control Value Table Cut In
   * Opcode range: 0x1D
   * Stack:        f26.6 -->
   */
  static void
  Ins_SCVTCI( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SSWCI[]:      Set Single Width Cut In
   * Opcode range: 0x1E
   * Stack:        f26.6 -->
   */
  static void
  Ins_SSWCI( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SSW[]:        Set Single Width
   * Opcode range: 0x1F
   * Stack:        int32? -->
   */
  static void
  Ins_SSW( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * FLIPON[]:     Set auto-FLIP to ON
   * Opcode range: 0x4D
   * Stack:        -->
   */
  static void
  Ins_FLIPON( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * FLIPOFF[]:    Set auto-FLIP to OFF
   * Opcode range: 0x4E
   * Stack:        -->
   */
  static void
  Ins_FLIPOFF( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * SANGW[]:      Set ANGle Weight
   * Opcode range: 0x7E
   * Stack:        uint32 -->
   */
  static void
  Ins_SANGW( void )
  {}


  /**************************************************************************
   *
   * SDB[]:        Set Delta Base
   * Opcode range: 0x5E
   * Stack:        uint32 -->
   */
  static void
  Ins_SDB( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SDS[]:        Set Delta Shift
   * Opcode range: 0x5F
   * Stack:        uint32 -->
   */
  static void
  Ins_SDS( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * RTHG[]:       Round To Half Grid
   * Opcode range: 0x19
   * Stack:        -->
   */
  static void
  Ins_RTHG( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * RTG[]:        Round To Grid
   * Opcode range: 0x18
   * Stack:        -->
   */
  static void
  Ins_RTG( TT_ExecContext  exc )
  {}


  /**************************************************************************
   * RTDG[]:       Round To Double Grid
   * Opcode range: 0x3D
   * Stack:        -->
   */
  static void
  Ins_RTDG( TT_ExecContext  exc )
  {}


  /**************************************************************************
   * RUTG[]:       Round Up To Grid
   * Opcode range: 0x7C
   * Stack:        -->
   */
  static void
  Ins_RUTG( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * RDTG[]:       Round Down To Grid
   * Opcode range: 0x7D
   * Stack:        -->
   */
  static void
  Ins_RDTG( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * ROFF[]:       Round OFF
   * Opcode range: 0x7A
   * Stack:        -->
   */
  static void
  Ins_ROFF( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * SROUND[]:     Super ROUND
   * Opcode range: 0x76
   * Stack:        Eint8 -->
   */
  static void
  Ins_SROUND( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * S45ROUND[]:   Super ROUND 45 degrees
   * Opcode range: 0x77
   * Stack:        uint32 -->
   */
  static void
  Ins_S45ROUND( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * SDPvTL[a]:    Set Dual PVector to Line
   * Opcode range: 0x86-0x87
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_SDPVTL( TT_ExecContext  exc,
              FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SZP0[]:       Set Zone Pointer 0
   * Opcode range: 0x13
   * Stack:        uint32 -->
   */
  static void
  Ins_SZP0( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SZP1[]:       Set Zone Pointer 1
   * Opcode range: 0x14
   * Stack:        uint32 -->
   */
  static void
  Ins_SZP1( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SZP2[]:       Set Zone Pointer 2
   * Opcode range: 0x15
   * Stack:        uint32 -->
   */
  static void
  Ins_SZP2( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SZPS[]:       Set Zone PointerS
   * Opcode range: 0x16
   * Stack:        uint32 -->
   */
  static void
  Ins_SZPS( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * INSTCTRL[]:   INSTruction ConTRoL
   * Opcode range: 0x8E
   * Stack:        int32 int32 -->
   */
  static void
  Ins_INSTCTRL( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SCANCTRL[]:   SCAN ConTRoL
   * Opcode range: 0x85
   * Stack:        uint32? -->
   */
  static void
  Ins_SCANCTRL( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SCANTYPE[]:   SCAN TYPE
   * Opcode range: 0x8D
   * Stack:        uint16 -->
   */
  static void
  Ins_SCANTYPE( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MANAGING OUTLINES
   *
   */


  /**************************************************************************
   *
   * FLIPPT[]:     FLIP PoinT
   * Opcode range: 0x80
   * Stack:        uint32... -->
   */
  static void
  Ins_FLIPPT( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * FLIPRGON[]:   FLIP RanGe ON
   * Opcode range: 0x81
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_FLIPRGON( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * FLIPRGOFF:    FLIP RanGe OFF
   * Opcode range: 0x82
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_FLIPRGOFF( TT_ExecContext  exc,
                 FT_Long*        args )
  {}


  static FT_Bool
  Compute_Point_Displacement( TT_ExecContext  exc,
                              FT_F26Dot6*     x,
                              FT_F26Dot6*     y,
                              TT_GlyphZone    zone,
                              FT_UShort*      refp )
  {}


  /* See `ttinterp.h' for details on backward compatibility mode. */
  static void
  Move_Zp2_Point( TT_ExecContext  exc,
                  FT_UShort       point,
                  FT_F26Dot6      dx,
                  FT_F26Dot6      dy,
                  FT_Bool         touch )
  {}


  /**************************************************************************
   *
   * SHP[a]:       SHift Point by the last point
   * Opcode range: 0x32-0x33
   * Stack:        uint32... -->
   */
  static void
  Ins_SHP( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * SHZ[a]:       SHift Zone
   * Opcode range: 0x36-37
   * Stack:        uint32 -->
   */
  static void
  Ins_SHZ( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /**************************************************************************
   *
   * SHPIX[]:      SHift points by a PIXel amount
   * Opcode range: 0x38
   * Stack:        f26.6 uint32... -->
   */
  static void
  Ins_SHPIX( TT_ExecContext  exc,
             FT_Long*        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 )
  {}


  /**************************************************************************
   *
   * MDAP[a]:      Move Direct Absolute Point
   * Opcode range: 0x2E-0x2F
   * Stack:        uint32 -->
   */
  static void
  Ins_MDAP( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MIAP[a]:      Move Indirect Absolute Point
   * Opcode range: 0x3E-0x3F
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_MIAP( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MDRP[abcde]:  Move Direct Relative Point
   * Opcode range: 0xC0-0xDF
   * Stack:        uint32 -->
   */
  static void
  Ins_MDRP( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * MIRP[abcde]:  Move Indirect Relative Point
   * Opcode range: 0xE0-0xFF
   * Stack:        int32? uint32 -->
   */
  static void
  Ins_MIRP( TT_ExecContext  exc,
            FT_Long*        args )
  {}


  /**************************************************************************
   *
   * ALIGNRP[]:    ALIGN Relative Point
   * Opcode range: 0x3C
   * Stack:        uint32 uint32... -->
   */
  static void
  Ins_ALIGNRP( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * ISECT[]:      moves point to InterSECTion
   * Opcode range: 0x0F
   * Stack:        5 * uint32 -->
   */
  static void
  Ins_ISECT( TT_ExecContext  exc,
             FT_Long*        args )
  {}


  /**************************************************************************
   *
   * ALIGNPTS[]:   ALIGN PoinTS
   * Opcode range: 0x27
   * Stack:        uint32 uint32 -->
   */
  static void
  Ins_ALIGNPTS( TT_ExecContext  exc,
                FT_Long*        args )
  {}


  /**************************************************************************
   *
   * IP[]:         Interpolate Point
   * Opcode range: 0x39
   * Stack:        uint32... -->
   */

  /* SOMETIMES, DUMBER CODE IS BETTER CODE */

  static void
  Ins_IP( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * UTP[a]:       UnTouch Point
   * Opcode range: 0x29
   * Stack:        uint32 -->
   */
  static void
  Ins_UTP( TT_ExecContext  exc,
           FT_Long*        args )
  {}


  /* Local variables for Ins_IUP: */
  IUP_Worker;


  static void
  iup_worker_shift_( IUP_Worker  worker,
                     FT_UInt     p1,
                     FT_UInt     p2,
                     FT_UInt     p )
  {}


  static void
  iup_worker_interpolate_( IUP_Worker  worker,
                           FT_UInt     p1,
                           FT_UInt     p2,
                           FT_UInt     ref1,
                           FT_UInt     ref2 )
  {}


  /**************************************************************************
   *
   * IUP[a]:       Interpolate Untouched Points
   * Opcode range: 0x30-0x31
   * Stack:        -->
   */
  static void
  Ins_IUP( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * 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 )
  {}


  /**************************************************************************
   *
   * MISC. INSTRUCTIONS
   *
   */


  /**************************************************************************
   *
   * GETINFO[]:    GET INFOrmation
   * Opcode range: 0x88
   * Stack:        uint32 --> uint32
   */
  static void
  Ins_GETINFO( TT_ExecContext  exc,
               FT_Long*        args )
  {}


#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

  /**************************************************************************
   *
   * GETVARIATION[]: get normalized variation (blend) coordinates
   * Opcode range: 0x91
   * Stack:        --> f2.14...
   *
   * XXX: UNDOCUMENTED!  There is no official documentation from Apple for
   *      this bytecode instruction.  Active only if a font has GX
   *      variation axes.
   */
  static void
  Ins_GETVARIATION( TT_ExecContext  exc,
                    FT_Long*        args )
  {}


  /**************************************************************************
   *
   * GETDATA[]:    no idea what this is good for
   * Opcode range: 0x92
   * Stack:        --> 17
   *
   * XXX: UNDOCUMENTED!  There is no documentation from Apple for this
   *      very weird bytecode instruction.
   */
  static void
  Ins_GETDATA( FT_Long*  args )
  {}

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */


  static void
  Ins_UNKNOWN( TT_ExecContext  exc )
  {}


  /**************************************************************************
   *
   * 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( void*  exec )
  {}

#else /* !TT_USE_BYTECODE_INTERPRETER */

  /* ANSI C doesn't like empty source files */
  typedef int  tt_interp_dummy_;

#endif /* !TT_USE_BYTECODE_INTERPRETER */


/* END */