ttinterp.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:250k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttinterp.c                                                             */
  4. /*                                                                         */
  5. /*    TrueType bytecode interpreter (body).                                */
  6. /*                                                                         */
  7. /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_CALC_H
  20. #include FT_TRIGONOMETRY_H
  21. #include FT_SYSTEM_H
  22. #include "ttinterp.h"
  23. #include "tterrors.h"
  24. #ifdef TT_USE_BYTECODE_INTERPRETER
  25. #define TT_MULFIX           FT_MulFix
  26. #define TT_MULDIV           FT_MulDiv
  27. #define TT_MULDIV_NO_ROUND  FT_MulDiv_No_Round
  28.   /*************************************************************************/
  29.   /*                                                                       */
  30.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  31.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  32.   /* messages during execution.                                            */
  33.   /*                                                                       */
  34. #undef  FT_COMPONENT
  35. #define FT_COMPONENT  trace_ttinterp
  36.   /*************************************************************************/
  37.   /*                                                                       */
  38.   /* In order to detect infinite loops in the code, we set up a counter    */
  39.   /* within the run loop.  A single stroke of interpretation is now        */
  40.   /* limited to a maximal number of opcodes defined below.                 */
  41.   /*                                                                       */
  42. #define MAX_RUNNABLE_OPCODES  1000000L
  43.   /*************************************************************************/
  44.   /*                                                                       */
  45.   /* There are two kinds of implementations:                               */
  46.   /*                                                                       */
  47.   /* a. static implementation                                              */
  48.   /*                                                                       */
  49.   /*    The current execution context is a static variable, which fields   */
  50.   /*    are accessed directly by the interpreter during execution.  The    */
  51.   /*    context is named `cur'.                                            */
  52.   /*                                                                       */
  53.   /*    This version is non-reentrant, of course.                          */
  54.   /*                                                                       */
  55.   /* b. indirect implementation                                            */
  56.   /*                                                                       */
  57.   /*    The current execution context is passed to _each_ function as its  */
  58.   /*    first argument, and each field is thus accessed indirectly.        */
  59.   /*                                                                       */
  60.   /*    This version is fully re-entrant.                                  */
  61.   /*                                                                       */
  62.   /* The idea is that an indirect implementation may be slower to execute  */
  63.   /* on low-end processors that are used in some systems (like 386s or     */
  64.   /* even 486s).                                                           */
  65.   /*                                                                       */
  66.   /* As a consequence, the indirect implementation is now the default, as  */
  67.   /* its performance costs can be considered negligible in our context.    */
  68.   /* Note, however, that we kept the same source with macros because:      */
  69.   /*                                                                       */
  70.   /* - The code is kept very close in design to the Pascal code used for   */
  71.   /*   development.                                                        */
  72.   /*                                                                       */
  73.   /* - It's much more readable that way!                                   */
  74.   /*                                                                       */
  75.   /* - It's still open to experimentation and tuning.                      */
  76.   /*                                                                       */
  77.   /*************************************************************************/
  78. #ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */
  79. #define CUR  (*exc)                             /* see ttobjs.h */
  80.   /*************************************************************************/
  81.   /*                                                                       */
  82.   /* This macro is used whenever `exec' is unused in a function, to avoid  */
  83.   /* stupid warnings from pedantic compilers.                              */
  84.   /*                                                                       */
  85. #define FT_UNUSED_EXEC  FT_UNUSED( exc )
  86. #else                                           /* static implementation */
  87. #define CUR  cur
  88. #define FT_UNUSED_EXEC  int  __dummy = __dummy
  89.   static
  90.   TT_ExecContextRec  cur;   /* static exec. context variable */
  91.   /* apparently, we have a _lot_ of direct indexing when accessing  */
  92.   /* the static `cur', which makes the code bigger (due to all the  */
  93.   /* four bytes addresses).                                         */
  94. #endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
  95.   /*************************************************************************/
  96.   /*                                                                       */
  97.   /* The instruction argument stack.                                       */
  98.   /*                                                                       */
  99. #define INS_ARG  EXEC_OP_ FT_Long*  args    /* see ttobjs.h for EXEC_OP_ */
  100.   /*************************************************************************/
  101.   /*                                                                       */
  102.   /* This macro is used whenever `args' is unused in a function, to avoid  */
  103.   /* stupid warnings from pedantic compilers.                              */
  104.   /*                                                                       */
  105. #define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )
  106.   /*************************************************************************/
  107.   /*                                                                       */
  108.   /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
  109.   /* increase readability of the code.                                     */
  110.   /*                                                                       */
  111.   /*************************************************************************/
  112. #define SKIP_Code() 
  113.           SkipCode( EXEC_ARG )
  114. #define GET_ShortIns() 
  115.           GetShortIns( EXEC_ARG )
  116. #define NORMalize( x, y, v ) 
  117.           Normalize( EXEC_ARG_ x, y, v )
  118. #define SET_SuperRound( scale, flags ) 
  119.           SetSuperRound( EXEC_ARG_ scale, flags )
  120. #define ROUND_None( d, c ) 
  121.           Round_None( EXEC_ARG_ d, c )
  122. #define INS_Goto_CodeRange( range, ip ) 
  123.           Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
  124. #define CUR_Func_move( z, p, d ) 
  125.           CUR.func_move( EXEC_ARG_ z, p, d )
  126. #define CUR_Func_move_orig( z, p, d ) 
  127.           CUR.func_move_orig( EXEC_ARG_ z, p, d )
  128. #define CUR_Func_round( d, c ) 
  129.           CUR.func_round( EXEC_ARG_ d, c )
  130. #define CUR_Func_read_cvt( index ) 
  131.           CUR.func_read_cvt( EXEC_ARG_ index )
  132. #define CUR_Func_write_cvt( index, val ) 
  133.           CUR.func_write_cvt( EXEC_ARG_ index, val )
  134. #define CUR_Func_move_cvt( index, val ) 
  135.           CUR.func_move_cvt( EXEC_ARG_ index, val )
  136. #define CURRENT_Ratio() 
  137.           Current_Ratio( EXEC_ARG )
  138. #define CURRENT_Ppem() 
  139.           Current_Ppem( EXEC_ARG )
  140. #define CUR_Ppem() 
  141.           Cur_PPEM( EXEC_ARG )
  142. #define INS_SxVTL( a, b, c, d ) 
  143.           Ins_SxVTL( EXEC_ARG_ a, b, c, d )
  144. #define COMPUTE_Funcs() 
  145.           Compute_Funcs( EXEC_ARG )
  146. #define COMPUTE_Round( a ) 
  147.           Compute_Round( EXEC_ARG_ a )
  148. #define COMPUTE_Point_Displacement( a, b, c, d ) 
  149.           Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
  150. #define MOVE_Zp2_Point( a, b, c, t ) 
  151.           Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
  152. #define CUR_Func_project( v1, v2 )  
  153.           CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
  154. #define CUR_Func_dualproj( v1, v2 )  
  155.           CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
  156. #define CUR_fast_project( v ) 
  157.           CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
  158. #define CUR_fast_dualproj( v ) 
  159.           CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
  160.   /*************************************************************************/
  161.   /*                                                                       */
  162.   /* Instruction dispatch function, as used by the interpreter.            */
  163.   /*                                                                       */
  164.   typedef void  (*TInstruction_Function)( INS_ARG );
  165.   /*************************************************************************/
  166.   /*                                                                       */
  167.   /* A simple bounds-checking macro.                                       */
  168.   /*                                                                       */
  169. #define BOUNDS( x, n )  ( (FT_UInt)(x) >= (FT_UInt)(n) )
  170. #undef  SUCCESS
  171. #define SUCCESS  0
  172. #undef  FAILURE
  173. #define FAILURE  1
  174. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  175. #define GUESS_VECTOR( V )                                         
  176.   if ( CUR.face->unpatented_hinting )                             
  177.   {                                                               
  178.     CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); 
  179.     CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); 
  180.   }
  181. #else
  182. #define GUESS_VECTOR( V )
  183. #endif
  184.   /*************************************************************************/
  185.   /*                                                                       */
  186.   /*                        CODERANGE FUNCTIONS                            */
  187.   /*                                                                       */
  188.   /*************************************************************************/
  189.   /*************************************************************************/
  190.   /*                                                                       */
  191.   /* <Function>                                                            */
  192.   /*    TT_Goto_CodeRange                                                  */
  193.   /*                                                                       */
  194.   /* <Description>                                                         */
  195.   /*    Switches to a new code range (updates the code related elements in */
  196.   /*    `exec', and `IP').                                                 */
  197.   /*                                                                       */
  198.   /* <Input>                                                               */
  199.   /*    range :: The new execution code range.                             */
  200.   /*                                                                       */
  201.   /*    IP    :: The new IP in the new code range.                         */
  202.   /*                                                                       */
  203.   /* <InOut>                                                               */
  204.   /*    exec  :: The target execution context.                             */
  205.   /*                                                                       */
  206.   /* <Return>                                                              */
  207.   /*    FreeType error code.  0 means success.                             */
  208.   /*                                                                       */
  209.   FT_LOCAL_DEF( FT_Error )
  210.   TT_Goto_CodeRange( TT_ExecContext  exec,
  211.                      FT_Int          range,
  212.                      FT_Long         IP )
  213.   {
  214.     TT_CodeRange*  coderange;
  215.     FT_ASSERT( range >= 1 && range <= 3 );
  216.     coderange = &exec->codeRangeTable[range - 1];
  217.     FT_ASSERT( coderange->base != NULL );
  218.     /* NOTE: Because the last instruction of a program may be a CALL */
  219.     /*       which will return to the first byte *after* the code    */
  220.     /*       range, we test for IP <= Size instead of IP < Size.     */
  221.     /*                                                               */
  222.     FT_ASSERT( (FT_ULong)IP <= coderange->size );
  223.     exec->code     = coderange->base;
  224.     exec->codeSize = coderange->size;
  225.     exec->IP       = IP;
  226.     exec->curRange = range;
  227.     return TT_Err_Ok;
  228.   }
  229.   /*************************************************************************/
  230.   /*                                                                       */
  231.   /* <Function>                                                            */
  232.   /*    TT_Set_CodeRange                                                   */
  233.   /*                                                                       */
  234.   /* <Description>                                                         */
  235.   /*    Sets a code range.                                                 */
  236.   /*                                                                       */
  237.   /* <Input>                                                               */
  238.   /*    range  :: The code range index.                                    */
  239.   /*                                                                       */
  240.   /*    base   :: The new code base.                                       */
  241.   /*                                                                       */
  242.   /*    length :: The range size in bytes.                                 */
  243.   /*                                                                       */
  244.   /* <InOut>                                                               */
  245.   /*    exec   :: The target execution context.                            */
  246.   /*                                                                       */
  247.   /* <Return>                                                              */
  248.   /*    FreeType error code.  0 means success.                             */
  249.   /*                                                                       */
  250.   FT_LOCAL_DEF( FT_Error )
  251.   TT_Set_CodeRange( TT_ExecContext  exec,
  252.                     FT_Int          range,
  253.                     void*           base,
  254.                     FT_Long         length )
  255.   {
  256.     FT_ASSERT( range >= 1 && range <= 3 );
  257.     exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
  258.     exec->codeRangeTable[range - 1].size = length;
  259.     return TT_Err_Ok;
  260.   }
  261.   /*************************************************************************/
  262.   /*                                                                       */
  263.   /* <Function>                                                            */
  264.   /*    TT_Clear_CodeRange                                                 */
  265.   /*                                                                       */
  266.   /* <Description>                                                         */
  267.   /*    Clears a code range.                                               */
  268.   /*                                                                       */
  269.   /* <Input>                                                               */
  270.   /*    range :: The code range index.                                     */
  271.   /*                                                                       */
  272.   /* <InOut>                                                               */
  273.   /*    exec  :: The target execution context.                             */
  274.   /*                                                                       */
  275.   /* <Return>                                                              */
  276.   /*    FreeType error code.  0 means success.                             */
  277.   /*                                                                       */
  278.   /* <Note>                                                                */
  279.   /*    Does not set the Error variable.                                   */
  280.   /*                                                                       */
  281.   FT_LOCAL_DEF( FT_Error )
  282.   TT_Clear_CodeRange( TT_ExecContext  exec,
  283.                       FT_Int          range )
  284.   {
  285.     FT_ASSERT( range >= 1 && range <= 3 );
  286.     exec->codeRangeTable[range - 1].base = NULL;
  287.     exec->codeRangeTable[range - 1].size = 0;
  288.     return TT_Err_Ok;
  289.   }
  290.   /*************************************************************************/
  291.   /*                                                                       */
  292.   /*                   EXECUTION CONTEXT ROUTINES                          */
  293.   /*                                                                       */
  294.   /*************************************************************************/
  295.   /*************************************************************************/
  296.   /*                                                                       */
  297.   /* <Function>                                                            */
  298.   /*    TT_Done_Context                                                    */
  299.   /*                                                                       */
  300.   /* <Description>                                                         */
  301.   /*    Destroys a given context.                                          */
  302.   /*                                                                       */
  303.   /* <Input>                                                               */
  304.   /*    exec   :: A handle to the target execution context.                */
  305.   /*                                                                       */
  306.   /*    memory :: A handle to the parent memory object.                    */
  307.   /*                                                                       */
  308.   /* <Return>                                                              */
  309.   /*    FreeType error code.  0 means success.                             */
  310.   /*                                                                       */
  311.   /* <Note>                                                                */
  312.   /*    Only the glyph loader and debugger should call this function.      */
  313.   /*                                                                       */
  314.   FT_LOCAL_DEF( FT_Error )
  315.   TT_Done_Context( TT_ExecContext  exec )
  316.   {
  317.     FT_Memory  memory = exec->memory;
  318.     /* points zone */
  319.     exec->maxPoints   = 0;
  320.     exec->maxContours = 0;
  321.     /* free stack */
  322.     FT_FREE( exec->stack );
  323.     exec->stackSize = 0;
  324.     /* free call stack */
  325.     FT_FREE( exec->callStack );
  326.     exec->callSize = 0;
  327.     exec->callTop  = 0;
  328.     /* free glyph code range */
  329.     FT_FREE( exec->glyphIns );
  330.     exec->glyphSize = 0;
  331.     exec->size = NULL;
  332.     exec->face = NULL;
  333.     FT_FREE( exec );
  334.     return TT_Err_Ok;
  335.   }
  336.   /*************************************************************************/
  337.   /*                                                                       */
  338.   /* <Function>                                                            */
  339.   /*    Init_Context                                                       */
  340.   /*                                                                       */
  341.   /* <Description>                                                         */
  342.   /*    Initializes a context object.                                      */
  343.   /*                                                                       */
  344.   /* <Input>                                                               */
  345.   /*    memory :: A handle to the parent memory object.                    */
  346.   /*                                                                       */
  347.   /* <InOut>                                                               */
  348.   /*    exec   :: A handle to the target execution context.                */
  349.   /*                                                                       */
  350.   /* <Return>                                                              */
  351.   /*    FreeType error code.  0 means success.                             */
  352.   /*                                                                       */
  353.   static FT_Error
  354.   Init_Context( TT_ExecContext  exec,
  355.                 FT_Memory       memory )
  356.   {
  357.     FT_Error  error;
  358.     FT_TRACE1(( "Init_Context: new object at 0x%08pn", exec ));
  359.     exec->memory   = memory;
  360.     exec->callSize = 32;
  361.     if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )
  362.       goto Fail_Memory;
  363.     /* all values in the context are set to 0 already, but this is */
  364.     /* here as a remainder                                         */
  365.     exec->maxPoints   = 0;
  366.     exec->maxContours = 0;
  367.     exec->stackSize = 0;
  368.     exec->glyphSize = 0;
  369.     exec->stack     = NULL;
  370.     exec->glyphIns  = NULL;
  371.     exec->face = NULL;
  372.     exec->size = NULL;
  373.     return TT_Err_Ok;
  374.   Fail_Memory:
  375.     FT_ERROR(( "Init_Context: not enough memory for 0x%08lxn",
  376.                (FT_Long)exec ));
  377.     TT_Done_Context( exec );
  378.     return error;
  379.  }
  380.   /*************************************************************************/
  381.   /*                                                                       */
  382.   /* <Function>                                                            */
  383.   /*    Update_Max                                                         */
  384.   /*                                                                       */
  385.   /* <Description>                                                         */
  386.   /*    Checks the size of a buffer and reallocates it if necessary.       */
  387.   /*                                                                       */
  388.   /* <Input>                                                               */
  389.   /*    memory     :: A handle to the parent memory object.                */
  390.   /*                                                                       */
  391.   /*    multiplier :: The size in bytes of each element in the buffer.     */
  392.   /*                                                                       */
  393.   /*    new_max    :: The new capacity (size) of the buffer.               */
  394.   /*                                                                       */
  395.   /* <InOut>                                                               */
  396.   /*    size       :: The address of the buffer's current size expressed   */
  397.   /*                  in elements.                                         */
  398.   /*                                                                       */
  399.   /*    buff       :: The address of the buffer base pointer.              */
  400.   /*                                                                       */
  401.   /* <Return>                                                              */
  402.   /*    FreeType error code.  0 means success.                             */
  403.   /*                                                                       */
  404.   static FT_Error
  405.   Update_Max( FT_Memory  memory,
  406.               FT_ULong*  size,
  407.               FT_Long    multiplier,
  408.               void*      _pbuff,
  409.               FT_ULong   new_max )
  410.   {
  411.     FT_Error  error;
  412.     void**    pbuff = (void**)_pbuff;
  413.     if ( *size < new_max )
  414.     {
  415.       if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
  416.         return error;
  417.       *size = new_max;
  418.     }
  419.     return TT_Err_Ok;
  420.   }
  421.   /*************************************************************************/
  422.   /*                                                                       */
  423.   /* <Function>                                                            */
  424.   /*    TT_Load_Context                                                    */
  425.   /*                                                                       */
  426.   /* <Description>                                                         */
  427.   /*    Prepare an execution context for glyph hinting.                    */
  428.   /*                                                                       */
  429.   /* <Input>                                                               */
  430.   /*    face :: A handle to the source face object.                        */
  431.   /*                                                                       */
  432.   /*    size :: A handle to the source size object.                        */
  433.   /*                                                                       */
  434.   /* <InOut>                                                               */
  435.   /*    exec :: A handle to the target execution context.                  */
  436.   /*                                                                       */
  437.   /* <Return>                                                              */
  438.   /*    FreeType error code.  0 means success.                             */
  439.   /*                                                                       */
  440.   /* <Note>                                                                */
  441.   /*    Only the glyph loader and debugger should call this function.      */
  442.   /*                                                                       */
  443.   FT_LOCAL_DEF( FT_Error )
  444.   TT_Load_Context( TT_ExecContext  exec,
  445.                    TT_Face         face,
  446.                    TT_Size         size )
  447.   {
  448.     FT_Int          i;
  449.     FT_ULong        tmp;
  450.     TT_MaxProfile*  maxp;
  451.     FT_Error        error;
  452.     exec->face = face;
  453.     maxp       = &face->max_profile;
  454.     exec->size = size;
  455.     if ( size )
  456.     {
  457.       exec->numFDefs   = size->num_function_defs;
  458.       exec->maxFDefs   = size->max_function_defs;
  459.       exec->numIDefs   = size->num_instruction_defs;
  460.       exec->maxIDefs   = size->max_instruction_defs;
  461.       exec->FDefs      = size->function_defs;
  462.       exec->IDefs      = size->instruction_defs;
  463.       exec->tt_metrics = size->ttmetrics;
  464.       exec->metrics    = size->metrics;
  465.       exec->maxFunc    = size->max_func;
  466.       exec->maxIns     = size->max_ins;
  467.       for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
  468.         exec->codeRangeTable[i] = size->codeRangeTable[i];
  469.       /* set graphics state */
  470.       exec->GS = size->GS;
  471.       exec->cvtSize = size->cvt_size;
  472.       exec->cvt     = size->cvt;
  473.       exec->storeSize = size->storage_size;
  474.       exec->storage   = size->storage;
  475.       exec->twilight  = size->twilight;
  476.     }
  477.     /* XXX: We reserve a little more elements on the stack to deal safely */
  478.     /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
  479.     tmp = exec->stackSize;
  480.     error = Update_Max( exec->memory,
  481.                         &tmp,
  482.                         sizeof ( FT_F26Dot6 ),
  483.                         (void*)&exec->stack,
  484.                         maxp->maxStackElements + 32 );
  485.     exec->stackSize = (FT_UInt)tmp;
  486.     if ( error )
  487.       return error;
  488.     tmp = exec->glyphSize;
  489.     error = Update_Max( exec->memory,
  490.                         &tmp,
  491.                         sizeof ( FT_Byte ),
  492.                         (void*)&exec->glyphIns,
  493.                         maxp->maxSizeOfInstructions );
  494.     exec->glyphSize = (FT_UShort)tmp;
  495.     if ( error )
  496.       return error;
  497.     exec->pts.n_points   = 0;
  498.     exec->pts.n_contours = 0;
  499.     exec->zp1 = exec->pts;
  500.     exec->zp2 = exec->pts;
  501.     exec->zp0 = exec->pts;
  502.     exec->instruction_trap = FALSE;
  503.     return TT_Err_Ok;
  504.   }
  505.   /*************************************************************************/
  506.   /*                                                                       */
  507.   /* <Function>                                                            */
  508.   /*    TT_Save_Context                                                    */
  509.   /*                                                                       */
  510.   /* <Description>                                                         */
  511.   /*    Saves the code ranges in a `size' object.                          */
  512.   /*                                                                       */
  513.   /* <Input>                                                               */
  514.   /*    exec :: A handle to the source execution context.                  */
  515.   /*                                                                       */
  516.   /* <InOut>                                                               */
  517.   /*    size :: A handle to the target size object.                        */
  518.   /*                                                                       */
  519.   /* <Return>                                                              */
  520.   /*    FreeType error code.  0 means success.                             */
  521.   /*                                                                       */
  522.   /* <Note>                                                                */
  523.   /*    Only the glyph loader and debugger should call this function.      */
  524.   /*                                                                       */
  525.   FT_LOCAL_DEF( FT_Error )
  526.   TT_Save_Context( TT_ExecContext  exec,
  527.                    TT_Size         size )
  528.   {
  529.     FT_Int  i;
  530.     /* XXXX: Will probably disappear soon with all the code range */
  531.     /*       management, which is now rather obsolete.            */
  532.     /*                                                            */
  533.     size->num_function_defs    = exec->numFDefs;
  534.     size->num_instruction_defs = exec->numIDefs;
  535.     size->max_func = exec->maxFunc;
  536.     size->max_ins  = exec->maxIns;
  537.     for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
  538.       size->codeRangeTable[i] = exec->codeRangeTable[i];
  539.     return TT_Err_Ok;
  540.   }
  541.   /*************************************************************************/
  542.   /*                                                                       */
  543.   /* <Function>                                                            */
  544.   /*    TT_Run_Context                                                     */
  545.   /*                                                                       */
  546.   /* <Description>                                                         */
  547.   /*    Executes one or more instructions in the execution context.        */
  548.   /*                                                                       */
  549.   /* <Input>                                                               */
  550.   /*    debug :: A Boolean flag.  If set, the function sets some internal  */
  551.   /*             variables and returns immediately, otherwise TT_RunIns()  */
  552.   /*             is called.                                                */
  553.   /*                                                                       */
  554.   /*             This is commented out currently.                          */
  555.   /*                                                                       */
  556.   /* <Input>                                                               */
  557.   /*    exec  :: A handle to the target execution context.                 */
  558.   /*                                                                       */
  559.   /* <Return>                                                              */
  560.   /*    TrueTyoe error code.  0 means success.                             */
  561.   /*                                                                       */
  562.   /* <Note>                                                                */
  563.   /*    Only the glyph loader and debugger should call this function.      */
  564.   /*                                                                       */
  565.   FT_LOCAL_DEF( FT_Error )
  566.   TT_Run_Context( TT_ExecContext  exec,
  567.                   FT_Bool         debug )
  568.   {
  569.     FT_Error  error;
  570.     if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0  ) )
  571.            != TT_Err_Ok )
  572.       return error;
  573.     exec->zp0 = exec->pts;
  574.     exec->zp1 = exec->pts;
  575.     exec->zp2 = exec->pts;
  576.     exec->GS.gep0 = 1;
  577.     exec->GS.gep1 = 1;
  578.     exec->GS.gep2 = 1;
  579.     exec->GS.projVector.x = 0x4000;
  580.     exec->GS.projVector.y = 0x0000;
  581.     exec->GS.freeVector = exec->GS.projVector;
  582.     exec->GS.dualVector = exec->GS.projVector;
  583. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  584.     exec->GS.both_x_axis = TRUE;
  585. #endif
  586.     exec->GS.round_state = 1;
  587.     exec->GS.loop        = 1;
  588.     /* some glyphs leave something on the stack. so we clean it */
  589.     /* before a new execution.                                  */
  590.     exec->top     = 0;
  591.     exec->callTop = 0;
  592. #if 1
  593.     FT_UNUSED( debug );
  594.     return exec->face->interpreter( exec );
  595. #else
  596.     if ( !debug )
  597.       return TT_RunIns( exec );
  598.     else
  599.       return TT_Err_Ok;
  600. #endif
  601.   }
  602.   const TT_GraphicsState  tt_default_graphics_state =
  603.   {
  604.     0, 0, 0,
  605.     { 0x4000, 0 },
  606.     { 0x4000, 0 },
  607.     { 0x4000, 0 },
  608. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  609.     TRUE,
  610. #endif
  611.     1, 64, 1,
  612.     TRUE, 68, 0, 0, 9, 3,
  613.     0, FALSE, 2, 1, 1, 1
  614.   };
  615.   /* documentation is in ttinterp.h */
  616.   FT_EXPORT_DEF( TT_ExecContext )
  617.   TT_New_Context( TT_Driver  driver )
  618.   {
  619.     TT_ExecContext  exec;
  620.     FT_Memory       memory;
  621.     memory = driver->root.root.memory;
  622.     exec   = driver->context;
  623.     if ( !driver->context )
  624.     {
  625.       FT_Error  error;
  626.       /* allocate object */
  627.       if ( FT_NEW( exec ) )
  628.         goto Exit;
  629.       /* initialize it */
  630.       error = Init_Context( exec, memory );
  631.       if ( error )
  632.         goto Fail;
  633.       /* store it into the driver */
  634.       driver->context = exec;
  635.     }
  636.   Exit:
  637.     return driver->context;
  638.   Fail:
  639.     FT_FREE( exec );
  640.     return 0;
  641.   }
  642.   /*************************************************************************/
  643.   /*                                                                       */
  644.   /* Before an opcode is executed, the interpreter verifies that there are */
  645.   /* enough arguments on the stack, with the help of the `Pop_Push_Count'  */
  646.   /* table.                                                                */
  647.   /*                                                                       */
  648.   /* For each opcode, the first column gives the number of arguments that  */
  649.   /* are popped from the stack; the second one gives the number of those   */
  650.   /* that are pushed in result.                                            */
  651.   /*                                                                       */
  652.   /* Opcodes which have a varying number of parameters in the data stream  */
  653.   /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */
  654.   /* the `opcode_length' table, and the value in `Pop_Push_Count' is set   */
  655.   /* to zero.                                                              */
  656.   /*                                                                       */
  657.   /*************************************************************************/
  658. #undef  PACK
  659. #define PACK( x, y )  ( ( x << 4 ) | y )
  660.   static
  661.   const FT_Byte  Pop_Push_Count[256] =
  662.   {
  663.     /* opcodes are gathered in groups of 16 */
  664.     /* please keep the spaces as they are   */
  665.     /*  SVTCA  y  */  PACK( 0, 0 ),
  666.     /*  SVTCA  x  */  PACK( 0, 0 ),
  667.     /*  SPvTCA y  */  PACK( 0, 0 ),
  668.     /*  SPvTCA x  */  PACK( 0, 0 ),
  669.     /*  SFvTCA y  */  PACK( 0, 0 ),
  670.     /*  SFvTCA x  */  PACK( 0, 0 ),
  671.     /*  SPvTL //  */  PACK( 2, 0 ),
  672.     /*  SPvTL +   */  PACK( 2, 0 ),
  673.     /*  SFvTL //  */  PACK( 2, 0 ),
  674.     /*  SFvTL +   */  PACK( 2, 0 ),
  675.     /*  SPvFS     */  PACK( 2, 0 ),
  676.     /*  SFvFS     */  PACK( 2, 0 ),
  677.     /*  GPV       */  PACK( 0, 2 ),
  678.     /*  GFV       */  PACK( 0, 2 ),
  679.     /*  SFvTPv    */  PACK( 0, 0 ),
  680.     /*  ISECT     */  PACK( 5, 0 ),
  681.     /*  SRP0      */  PACK( 1, 0 ),
  682.     /*  SRP1      */  PACK( 1, 0 ),
  683.     /*  SRP2      */  PACK( 1, 0 ),
  684.     /*  SZP0      */  PACK( 1, 0 ),
  685.     /*  SZP1      */  PACK( 1, 0 ),
  686.     /*  SZP2      */  PACK( 1, 0 ),
  687.     /*  SZPS      */  PACK( 1, 0 ),
  688.     /*  SLOOP     */  PACK( 1, 0 ),
  689.     /*  RTG       */  PACK( 0, 0 ),
  690.     /*  RTHG      */  PACK( 0, 0 ),
  691.     /*  SMD       */  PACK( 1, 0 ),
  692.     /*  ELSE      */  PACK( 0, 0 ),
  693.     /*  JMPR      */  PACK( 1, 0 ),
  694.     /*  SCvTCi    */  PACK( 1, 0 ),
  695.     /*  SSwCi     */  PACK( 1, 0 ),
  696.     /*  SSW       */  PACK( 1, 0 ),
  697.     /*  DUP       */  PACK( 1, 2 ),
  698.     /*  POP       */  PACK( 1, 0 ),
  699.     /*  CLEAR     */  PACK( 0, 0 ),
  700.     /*  SWAP      */  PACK( 2, 2 ),
  701.     /*  DEPTH     */  PACK( 0, 1 ),
  702.     /*  CINDEX    */  PACK( 1, 1 ),
  703.     /*  MINDEX    */  PACK( 1, 0 ),
  704.     /*  AlignPTS  */  PACK( 2, 0 ),
  705.     /*  INS_$28   */  PACK( 0, 0 ),
  706.     /*  UTP       */  PACK( 1, 0 ),
  707.     /*  LOOPCALL  */  PACK( 2, 0 ),
  708.     /*  CALL      */  PACK( 1, 0 ),
  709.     /*  FDEF      */  PACK( 1, 0 ),
  710.     /*  ENDF      */  PACK( 0, 0 ),
  711.     /*  MDAP[0]   */  PACK( 1, 0 ),
  712.     /*  MDAP[1]   */  PACK( 1, 0 ),
  713.     /*  IUP[0]    */  PACK( 0, 0 ),
  714.     /*  IUP[1]    */  PACK( 0, 0 ),
  715.     /*  SHP[0]    */  PACK( 0, 0 ),
  716.     /*  SHP[1]    */  PACK( 0, 0 ),
  717.     /*  SHC[0]    */  PACK( 1, 0 ),
  718.     /*  SHC[1]    */  PACK( 1, 0 ),
  719.     /*  SHZ[0]    */  PACK( 1, 0 ),
  720.     /*  SHZ[1]    */  PACK( 1, 0 ),
  721.     /*  SHPIX     */  PACK( 1, 0 ),
  722.     /*  IP        */  PACK( 0, 0 ),
  723.     /*  MSIRP[0]  */  PACK( 2, 0 ),
  724.     /*  MSIRP[1]  */  PACK( 2, 0 ),
  725.     /*  AlignRP   */  PACK( 0, 0 ),
  726.     /*  RTDG      */  PACK( 0, 0 ),
  727.     /*  MIAP[0]   */  PACK( 2, 0 ),
  728.     /*  MIAP[1]   */  PACK( 2, 0 ),
  729.     /*  NPushB    */  PACK( 0, 0 ),
  730.     /*  NPushW    */  PACK( 0, 0 ),
  731.     /*  WS        */  PACK( 2, 0 ),
  732.     /*  RS        */  PACK( 1, 1 ),
  733.     /*  WCvtP     */  PACK( 2, 0 ),
  734.     /*  RCvt      */  PACK( 1, 1 ),
  735.     /*  GC[0]     */  PACK( 1, 1 ),
  736.     /*  GC[1]     */  PACK( 1, 1 ),
  737.     /*  SCFS      */  PACK( 2, 0 ),
  738.     /*  MD[0]     */  PACK( 2, 1 ),
  739.     /*  MD[1]     */  PACK( 2, 1 ),
  740.     /*  MPPEM     */  PACK( 0, 1 ),
  741.     /*  MPS       */  PACK( 0, 1 ),
  742.     /*  FlipON    */  PACK( 0, 0 ),
  743.     /*  FlipOFF   */  PACK( 0, 0 ),
  744.     /*  DEBUG     */  PACK( 1, 0 ),
  745.     /*  LT        */  PACK( 2, 1 ),
  746.     /*  LTEQ      */  PACK( 2, 1 ),
  747.     /*  GT        */  PACK( 2, 1 ),
  748.     /*  GTEQ      */  PACK( 2, 1 ),
  749.     /*  EQ        */  PACK( 2, 1 ),
  750.     /*  NEQ       */  PACK( 2, 1 ),
  751.     /*  ODD       */  PACK( 1, 1 ),
  752.     /*  EVEN      */  PACK( 1, 1 ),
  753.     /*  IF        */  PACK( 1, 0 ),
  754.     /*  EIF       */  PACK( 0, 0 ),
  755.     /*  AND       */  PACK( 2, 1 ),
  756.     /*  OR        */  PACK( 2, 1 ),
  757.     /*  NOT       */  PACK( 1, 1 ),
  758.     /*  DeltaP1   */  PACK( 1, 0 ),
  759.     /*  SDB       */  PACK( 1, 0 ),
  760.     /*  SDS       */  PACK( 1, 0 ),
  761.     /*  ADD       */  PACK( 2, 1 ),
  762.     /*  SUB       */  PACK( 2, 1 ),
  763.     /*  DIV       */  PACK( 2, 1 ),
  764.     /*  MUL       */  PACK( 2, 1 ),
  765.     /*  ABS       */  PACK( 1, 1 ),
  766.     /*  NEG       */  PACK( 1, 1 ),
  767.     /*  FLOOR     */  PACK( 1, 1 ),
  768.     /*  CEILING   */  PACK( 1, 1 ),
  769.     /*  ROUND[0]  */  PACK( 1, 1 ),
  770.     /*  ROUND[1]  */  PACK( 1, 1 ),
  771.     /*  ROUND[2]  */  PACK( 1, 1 ),
  772.     /*  ROUND[3]  */  PACK( 1, 1 ),
  773.     /*  NROUND[0] */  PACK( 1, 1 ),
  774.     /*  NROUND[1] */  PACK( 1, 1 ),
  775.     /*  NROUND[2] */  PACK( 1, 1 ),
  776.     /*  NROUND[3] */  PACK( 1, 1 ),
  777.     /*  WCvtF     */  PACK( 2, 0 ),
  778.     /*  DeltaP2   */  PACK( 1, 0 ),
  779.     /*  DeltaP3   */  PACK( 1, 0 ),
  780.     /*  DeltaCn[0] */ PACK( 1, 0 ),
  781.     /*  DeltaCn[1] */ PACK( 1, 0 ),
  782.     /*  DeltaCn[2] */ PACK( 1, 0 ),
  783.     /*  SROUND    */  PACK( 1, 0 ),
  784.     /*  S45Round  */  PACK( 1, 0 ),
  785.     /*  JROT      */  PACK( 2, 0 ),
  786.     /*  JROF      */  PACK( 2, 0 ),
  787.     /*  ROFF      */  PACK( 0, 0 ),
  788.     /*  INS_$7B   */  PACK( 0, 0 ),
  789.     /*  RUTG      */  PACK( 0, 0 ),
  790.     /*  RDTG      */  PACK( 0, 0 ),
  791.     /*  SANGW     */  PACK( 1, 0 ),
  792.     /*  AA        */  PACK( 1, 0 ),
  793.     /*  FlipPT    */  PACK( 0, 0 ),
  794.     /*  FlipRgON  */  PACK( 2, 0 ),
  795.     /*  FlipRgOFF */  PACK( 2, 0 ),
  796.     /*  INS_$83   */  PACK( 0, 0 ),
  797.     /*  INS_$84   */  PACK( 0, 0 ),
  798.     /*  ScanCTRL  */  PACK( 1, 0 ),
  799.     /*  SDVPTL[0] */  PACK( 2, 0 ),
  800.     /*  SDVPTL[1] */  PACK( 2, 0 ),
  801.     /*  GetINFO   */  PACK( 1, 1 ),
  802.     /*  IDEF      */  PACK( 1, 0 ),
  803.     /*  ROLL      */  PACK( 3, 3 ),
  804.     /*  MAX       */  PACK( 2, 1 ),
  805.     /*  MIN       */  PACK( 2, 1 ),
  806.     /*  ScanTYPE  */  PACK( 1, 0 ),
  807.     /*  InstCTRL  */  PACK( 2, 0 ),
  808.     /*  INS_$8F   */  PACK( 0, 0 ),
  809.     /*  INS_$90  */   PACK( 0, 0 ),
  810.     /*  INS_$91  */   PACK( 0, 0 ),
  811.     /*  INS_$92  */   PACK( 0, 0 ),
  812.     /*  INS_$93  */   PACK( 0, 0 ),
  813.     /*  INS_$94  */   PACK( 0, 0 ),
  814.     /*  INS_$95  */   PACK( 0, 0 ),
  815.     /*  INS_$96  */   PACK( 0, 0 ),
  816.     /*  INS_$97  */   PACK( 0, 0 ),
  817.     /*  INS_$98  */   PACK( 0, 0 ),
  818.     /*  INS_$99  */   PACK( 0, 0 ),
  819.     /*  INS_$9A  */   PACK( 0, 0 ),
  820.     /*  INS_$9B  */   PACK( 0, 0 ),
  821.     /*  INS_$9C  */   PACK( 0, 0 ),
  822.     /*  INS_$9D  */   PACK( 0, 0 ),
  823.     /*  INS_$9E  */   PACK( 0, 0 ),
  824.     /*  INS_$9F  */   PACK( 0, 0 ),
  825.     /*  INS_$A0  */   PACK( 0, 0 ),
  826.     /*  INS_$A1  */   PACK( 0, 0 ),
  827.     /*  INS_$A2  */   PACK( 0, 0 ),
  828.     /*  INS_$A3  */   PACK( 0, 0 ),
  829.     /*  INS_$A4  */   PACK( 0, 0 ),
  830.     /*  INS_$A5  */   PACK( 0, 0 ),
  831.     /*  INS_$A6  */   PACK( 0, 0 ),
  832.     /*  INS_$A7  */   PACK( 0, 0 ),
  833.     /*  INS_$A8  */   PACK( 0, 0 ),
  834.     /*  INS_$A9  */   PACK( 0, 0 ),
  835.     /*  INS_$AA  */   PACK( 0, 0 ),
  836.     /*  INS_$AB  */   PACK( 0, 0 ),
  837.     /*  INS_$AC  */   PACK( 0, 0 ),
  838.     /*  INS_$AD  */   PACK( 0, 0 ),
  839.     /*  INS_$AE  */   PACK( 0, 0 ),
  840.     /*  INS_$AF  */   PACK( 0, 0 ),
  841.     /*  PushB[0]  */  PACK( 0, 1 ),
  842.     /*  PushB[1]  */  PACK( 0, 2 ),
  843.     /*  PushB[2]  */  PACK( 0, 3 ),
  844.     /*  PushB[3]  */  PACK( 0, 4 ),
  845.     /*  PushB[4]  */  PACK( 0, 5 ),
  846.     /*  PushB[5]  */  PACK( 0, 6 ),
  847.     /*  PushB[6]  */  PACK( 0, 7 ),
  848.     /*  PushB[7]  */  PACK( 0, 8 ),
  849.     /*  PushW[0]  */  PACK( 0, 1 ),
  850.     /*  PushW[1]  */  PACK( 0, 2 ),
  851.     /*  PushW[2]  */  PACK( 0, 3 ),
  852.     /*  PushW[3]  */  PACK( 0, 4 ),
  853.     /*  PushW[4]  */  PACK( 0, 5 ),
  854.     /*  PushW[5]  */  PACK( 0, 6 ),
  855.     /*  PushW[6]  */  PACK( 0, 7 ),
  856.     /*  PushW[7]  */  PACK( 0, 8 ),
  857.     /*  MDRP[00]  */  PACK( 1, 0 ),
  858.     /*  MDRP[01]  */  PACK( 1, 0 ),
  859.     /*  MDRP[02]  */  PACK( 1, 0 ),
  860.     /*  MDRP[03]  */  PACK( 1, 0 ),
  861.     /*  MDRP[04]  */  PACK( 1, 0 ),
  862.     /*  MDRP[05]  */  PACK( 1, 0 ),
  863.     /*  MDRP[06]  */  PACK( 1, 0 ),
  864.     /*  MDRP[07]  */  PACK( 1, 0 ),
  865.     /*  MDRP[08]  */  PACK( 1, 0 ),
  866.     /*  MDRP[09]  */  PACK( 1, 0 ),
  867.     /*  MDRP[10]  */  PACK( 1, 0 ),
  868.     /*  MDRP[11]  */  PACK( 1, 0 ),
  869.     /*  MDRP[12]  */  PACK( 1, 0 ),
  870.     /*  MDRP[13]  */  PACK( 1, 0 ),
  871.     /*  MDRP[14]  */  PACK( 1, 0 ),
  872.     /*  MDRP[15]  */  PACK( 1, 0 ),
  873.     /*  MDRP[16]  */  PACK( 1, 0 ),
  874.     /*  MDRP[17]  */  PACK( 1, 0 ),
  875.     /*  MDRP[18]  */  PACK( 1, 0 ),
  876.     /*  MDRP[19]  */  PACK( 1, 0 ),
  877.     /*  MDRP[20]  */  PACK( 1, 0 ),
  878.     /*  MDRP[21]  */  PACK( 1, 0 ),
  879.     /*  MDRP[22]  */  PACK( 1, 0 ),
  880.     /*  MDRP[23]  */  PACK( 1, 0 ),
  881.     /*  MDRP[24]  */  PACK( 1, 0 ),
  882.     /*  MDRP[25]  */  PACK( 1, 0 ),
  883.     /*  MDRP[26]  */  PACK( 1, 0 ),
  884.     /*  MDRP[27]  */  PACK( 1, 0 ),
  885.     /*  MDRP[28]  */  PACK( 1, 0 ),
  886.     /*  MDRP[29]  */  PACK( 1, 0 ),
  887.     /*  MDRP[30]  */  PACK( 1, 0 ),
  888.     /*  MDRP[31]  */  PACK( 1, 0 ),
  889.     /*  MIRP[00]  */  PACK( 2, 0 ),
  890.     /*  MIRP[01]  */  PACK( 2, 0 ),
  891.     /*  MIRP[02]  */  PACK( 2, 0 ),
  892.     /*  MIRP[03]  */  PACK( 2, 0 ),
  893.     /*  MIRP[04]  */  PACK( 2, 0 ),
  894.     /*  MIRP[05]  */  PACK( 2, 0 ),
  895.     /*  MIRP[06]  */  PACK( 2, 0 ),
  896.     /*  MIRP[07]  */  PACK( 2, 0 ),
  897.     /*  MIRP[08]  */  PACK( 2, 0 ),
  898.     /*  MIRP[09]  */  PACK( 2, 0 ),
  899.     /*  MIRP[10]  */  PACK( 2, 0 ),
  900.     /*  MIRP[11]  */  PACK( 2, 0 ),
  901.     /*  MIRP[12]  */  PACK( 2, 0 ),
  902.     /*  MIRP[13]  */  PACK( 2, 0 ),
  903.     /*  MIRP[14]  */  PACK( 2, 0 ),
  904.     /*  MIRP[15]  */  PACK( 2, 0 ),
  905.     /*  MIRP[16]  */  PACK( 2, 0 ),
  906.     /*  MIRP[17]  */  PACK( 2, 0 ),
  907.     /*  MIRP[18]  */  PACK( 2, 0 ),
  908.     /*  MIRP[19]  */  PACK( 2, 0 ),
  909.     /*  MIRP[20]  */  PACK( 2, 0 ),
  910.     /*  MIRP[21]  */  PACK( 2, 0 ),
  911.     /*  MIRP[22]  */  PACK( 2, 0 ),
  912.     /*  MIRP[23]  */  PACK( 2, 0 ),
  913.     /*  MIRP[24]  */  PACK( 2, 0 ),
  914.     /*  MIRP[25]  */  PACK( 2, 0 ),
  915.     /*  MIRP[26]  */  PACK( 2, 0 ),
  916.     /*  MIRP[27]  */  PACK( 2, 0 ),
  917.     /*  MIRP[28]  */  PACK( 2, 0 ),
  918.     /*  MIRP[29]  */  PACK( 2, 0 ),
  919.     /*  MIRP[30]  */  PACK( 2, 0 ),
  920.     /*  MIRP[31]  */  PACK( 2, 0 )
  921.   };
  922.   static
  923.   const FT_Char  opcode_length[256] =
  924.   {
  925.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  926.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  927.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  928.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  929.    -1,-2, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  930.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  931.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  932.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  933.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  934.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  935.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  936.     2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,
  937.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  938.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  939.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
  940.     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1
  941.   };
  942. #undef PACK
  943. #if 1
  944.   static FT_Int32
  945.   TT_MulFix14( FT_Int32  a,
  946.                FT_Int    b )
  947.   {
  948.     FT_Int32   sign;
  949.     FT_UInt32  ah, al, mid, lo, hi;
  950.     sign = a ^ b;
  951.     if ( a < 0 )
  952.       a = -a;
  953.     if ( b < 0 )
  954.       b = -b;
  955.     ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
  956.     al = (FT_UInt32)( a & 0xFFFFU );
  957.     lo    = al * b;
  958.     mid   = ah * b;
  959.     hi    = mid >> 16;
  960.     mid   = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
  961.     lo   += mid;
  962.     if ( lo < mid )
  963.       hi += 1;
  964.     mid = ( lo >> 14 ) | ( hi << 18 );
  965.     return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
  966.   }
  967. #else
  968.   /* compute (a*b)/2^14 with maximal accuracy and rounding */
  969.   static FT_Int32
  970.   TT_MulFix14( FT_Int32  a,
  971.                FT_Int    b )
  972.   {
  973.     FT_Int32   m, s, hi;
  974.     FT_UInt32  l, lo;
  975.     /* compute ax*bx as 64-bit value */
  976.     l  = (FT_UInt32)( ( a & 0xFFFFU ) * b );
  977.     m  = ( a >> 16 ) * b;
  978.     lo = l + (FT_UInt32)( m << 16 );
  979.     hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
  980.     /* divide the result by 2^14 with rounding */
  981.     s   = hi >> 31;
  982.     l   = lo + (FT_UInt32)s;
  983.     hi += s + ( l < lo );
  984.     lo  = l;
  985.     l   = lo + 0x2000U;
  986.     hi += l < lo;
  987.     return ( hi << 18 ) | ( l >> 14 );
  988.   }
  989. #endif
  990.   /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */
  991.   static FT_Int32
  992.   TT_DotFix14( FT_Int32  ax,
  993.                FT_Int32  ay,
  994.                FT_Int    bx,
  995.                FT_Int    by )
  996.   {
  997.     FT_Int32   m, s, hi1, hi2, hi;
  998.     FT_UInt32  l, lo1, lo2, lo;
  999.     /* compute ax*bx as 64-bit value */
  1000.     l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
  1001.     m = ( ax >> 16 ) * bx;
  1002.     lo1 = l + (FT_UInt32)( m << 16 );
  1003.     hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
  1004.     /* compute ay*by as 64-bit value */
  1005.     l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
  1006.     m = ( ay >> 16 ) * by;
  1007.     lo2 = l + (FT_UInt32)( m << 16 );
  1008.     hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
  1009.     /* add them */
  1010.     lo = lo1 + lo2;
  1011.     hi = hi1 + hi2 + ( lo < lo1 );
  1012.     /* divide the result by 2^14 with rounding */
  1013.     s   = hi >> 31;
  1014.     l   = lo + (FT_UInt32)s;
  1015.     hi += s + ( l < lo );
  1016.     lo  = l;
  1017.     l   = lo + 0x2000U;
  1018.     hi += ( l < lo );
  1019.     return ( hi << 18 ) | ( l >> 14 );
  1020.   }
  1021.   /* return length of given vector */
  1022. #if 0
  1023.   static FT_Int32
  1024.   TT_VecLen( FT_Int32  x,
  1025.              FT_Int32  y )
  1026.   {
  1027.     FT_Int32   m, hi1, hi2, hi;
  1028.     FT_UInt32  l, lo1, lo2, lo;
  1029.     /* compute x*x as 64-bit value */
  1030.     lo = (FT_UInt32)( x & 0xFFFFU );
  1031.     hi = x >> 16;
  1032.     l  = lo * lo;
  1033.     m  = hi * lo;
  1034.     hi = hi * hi;
  1035.     lo1 = l + (FT_UInt32)( m << 17 );
  1036.     hi1 = hi + ( m >> 15 ) + ( lo1 < l );
  1037.     /* compute y*y as 64-bit value */
  1038.     lo = (FT_UInt32)( y & 0xFFFFU );
  1039.     hi = y >> 16;
  1040.     l  = lo * lo;
  1041.     m  = hi * lo;
  1042.     hi = hi * hi;
  1043.     lo2 = l + (FT_UInt32)( m << 17 );
  1044.     hi2 = hi + ( m >> 15 ) + ( lo2 < l );
  1045.     /* add them to get 'x*x+y*y' as 64-bit value */
  1046.     lo = lo1 + lo2;
  1047.     hi = hi1 + hi2 + ( lo < lo1 );
  1048.     /* compute the square root of this value */
  1049.     {
  1050.       FT_UInt32  root, rem, test_div;
  1051.       FT_Int     count;
  1052.       root = 0;
  1053.       {
  1054.         rem   = 0;
  1055.         count = 32;
  1056.         do
  1057.         {
  1058.           rem      = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
  1059.           hi       = (  hi << 2 ) | (            lo >> 30 );
  1060.           lo     <<= 2;
  1061.           root   <<= 1;
  1062.           test_div = ( root << 1 ) + 1;
  1063.           if ( rem >= test_div )
  1064.           {
  1065.             rem  -= test_div;
  1066.             root += 1;
  1067.           }
  1068.         } while ( --count );
  1069.       }
  1070.       return (FT_Int32)root;
  1071.     }
  1072.   }
  1073. #else
  1074.   /* this version uses FT_Vector_Length which computes the same value */
  1075.   /* much, much faster..                                              */
  1076.   /*                                                                  */
  1077.   static FT_F26Dot6
  1078.   TT_VecLen( FT_F26Dot6  X,
  1079.              FT_F26Dot6  Y )
  1080.   {
  1081.     FT_Vector  v;
  1082.     v.x = X;
  1083.     v.y = Y;
  1084.     return FT_Vector_Length( &v );
  1085.   }
  1086. #endif
  1087.   /*************************************************************************/
  1088.   /*                                                                       */
  1089.   /* <Function>                                                            */
  1090.   /*    Current_Ratio                                                      */
  1091.   /*                                                                       */
  1092.   /* <Description>                                                         */
  1093.   /*    Returns the current aspect ratio scaling factor depending on the   */
  1094.   /*    projection vector's state and device resolutions.                  */
  1095.   /*                                                                       */
  1096.   /* <Return>                                                              */
  1097.   /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
  1098.   /*                                                                       */
  1099.   static FT_Long
  1100.   Current_Ratio( EXEC_OP )
  1101.   {
  1102.     if ( !CUR.tt_metrics.ratio )
  1103.     {
  1104. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  1105.       if ( CUR.face->unpatented_hinting )
  1106.       {
  1107.         if ( CUR.GS.both_x_axis )
  1108.           CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
  1109.         else
  1110.           CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
  1111.       }
  1112.       else
  1113. #endif
  1114.       {
  1115.         if ( CUR.GS.projVector.y == 0 )
  1116.           CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
  1117.         else if ( CUR.GS.projVector.x == 0 )
  1118.           CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
  1119.         else
  1120.         {
  1121.           FT_Long  x, y;
  1122.           x = TT_MULDIV( CUR.GS.projVector.x,
  1123.                          CUR.tt_metrics.x_ratio, 0x4000 );
  1124.           y = TT_MULDIV( CUR.GS.projVector.y,
  1125.                          CUR.tt_metrics.y_ratio, 0x4000 );
  1126.           CUR.tt_metrics.ratio = TT_VecLen( x, y );
  1127.         }
  1128.       }
  1129.     }
  1130.     return CUR.tt_metrics.ratio;
  1131.   }
  1132.   static FT_Long
  1133.   Current_Ppem( EXEC_OP )
  1134.   {
  1135.     return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
  1136.   }
  1137.   /*************************************************************************/
  1138.   /*                                                                       */
  1139.   /* Functions related to the control value table (CVT).                   */
  1140.   /*                                                                       */
  1141.   /*************************************************************************/
  1142.   FT_CALLBACK_DEF( FT_F26Dot6 )
  1143.   Read_CVT( EXEC_OP_ FT_ULong  idx )
  1144.   {
  1145.     return CUR.cvt[idx];
  1146.   }
  1147.   FT_CALLBACK_DEF( FT_F26Dot6 )
  1148.   Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )
  1149.   {
  1150.     return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() );
  1151.   }
  1152.   FT_CALLBACK_DEF( void )
  1153.   Write_CVT( EXEC_OP_ FT_ULong    idx,
  1154.                       FT_F26Dot6  value )
  1155.   {
  1156.     CUR.cvt[idx] = value;
  1157.   }
  1158.   FT_CALLBACK_DEF( void )
  1159.   Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
  1160.                                 FT_F26Dot6  value )
  1161.   {
  1162.     CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
  1163.   }
  1164.   FT_CALLBACK_DEF( void )
  1165.   Move_CVT( EXEC_OP_ FT_ULong    idx,
  1166.                      FT_F26Dot6  value )
  1167.   {
  1168.     CUR.cvt[idx] += value;
  1169.   }
  1170.   FT_CALLBACK_DEF( void )
  1171.   Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
  1172.                                FT_F26Dot6  value )
  1173.   {
  1174.     CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
  1175.   }
  1176.   /*************************************************************************/
  1177.   /*                                                                       */
  1178.   /* <Function>                                                            */
  1179.   /*    GetShortIns                                                        */
  1180.   /*                                                                       */
  1181.   /* <Description>                                                         */
  1182.   /*    Returns a short integer taken from the instruction stream at       */
  1183.   /*    address IP.                                                        */
  1184.   /*                                                                       */
  1185.   /* <Return>                                                              */
  1186.   /*    Short read at code[IP].                                            */
  1187.   /*                                                                       */
  1188.   /* <Note>                                                                */
  1189.   /*    This one could become a macro.                                     */
  1190.   /*                                                                       */
  1191.   static FT_Short
  1192.   GetShortIns( EXEC_OP )
  1193.   {
  1194.     /* Reading a byte stream so there is no endianess (DaveP) */
  1195.     CUR.IP += 2;
  1196.     return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
  1197.                          CUR.code[CUR.IP - 1]      );
  1198.   }
  1199.   /*************************************************************************/
  1200.   /*                                                                       */
  1201.   /* <Function>                                                            */
  1202.   /*    Ins_Goto_CodeRange                                                 */
  1203.   /*                                                                       */
  1204.   /* <Description>                                                         */
  1205.   /*    Goes to a certain code range in the instruction stream.            */
  1206.   /*                                                                       */
  1207.   /* <Input>                                                               */
  1208.   /*    aRange :: The index of the code range.                             */
  1209.   /*                                                                       */
  1210.   /*    aIP    :: The new IP address in the code range.                    */
  1211.   /*                                                                       */
  1212.   /* <Return>                                                              */
  1213.   /*    SUCCESS or FAILURE.                                                */
  1214.   /*                                                                       */
  1215.   static FT_Bool
  1216.   Ins_Goto_CodeRange( EXEC_OP_ FT_Int    aRange,
  1217.                                FT_ULong  aIP )
  1218.   {
  1219.     TT_CodeRange*  range;
  1220.     if ( aRange < 1 || aRange > 3 )
  1221.     {
  1222.       CUR.error = TT_Err_Bad_Argument;
  1223.       return FAILURE;
  1224.     }
  1225.     range = &CUR.codeRangeTable[aRange - 1];
  1226.     if ( range->base == NULL )     /* invalid coderange */
  1227.     {
  1228.       CUR.error = TT_Err_Invalid_CodeRange;
  1229.       return FAILURE;
  1230.     }
  1231.     /* NOTE: Because the last instruction of a program may be a CALL */
  1232.     /*       which will return to the first byte *after* the code    */
  1233.     /*       range, we test for AIP <= Size, instead of AIP < Size.  */
  1234.     if ( aIP > range->size )
  1235.     {
  1236.       CUR.error = TT_Err_Code_Overflow;
  1237.       return FAILURE;
  1238.     }
  1239.     CUR.code     = range->base;
  1240.     CUR.codeSize = range->size;
  1241.     CUR.IP       = aIP;
  1242.     CUR.curRange = aRange;
  1243.     return SUCCESS;
  1244.   }
  1245.   /*************************************************************************/
  1246.   /*                                                                       */
  1247.   /* <Function>                                                            */
  1248.   /*    Direct_Move                                                        */
  1249.   /*                                                                       */
  1250.   /* <Description>                                                         */
  1251.   /*    Moves a point by a given distance along the freedom vector.  The   */
  1252.   /*    point will be `touched'.                                           */
  1253.   /*                                                                       */
  1254.   /* <Input>                                                               */
  1255.   /*    point    :: The index of the point to move.                        */
  1256.   /*                                                                       */
  1257.   /*    distance :: The distance to apply.                                 */
  1258.   /*                                                                       */
  1259.   /* <InOut>                                                               */
  1260.   /*    zone     :: The affected glyph zone.                               */
  1261.   /*                                                                       */
  1262.   static void
  1263.   Direct_Move( EXEC_OP_ TT_GlyphZone  zone,
  1264.                         FT_UShort     point,
  1265.                         FT_F26Dot6    distance )
  1266.   {
  1267.     FT_F26Dot6  v;
  1268. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  1269.     FT_ASSERT( !CUR.face->unpatented_hinting );
  1270. #endif
  1271.     v = CUR.GS.freeVector.x;
  1272.     if ( v != 0 )
  1273.     {
  1274.       zone->cur[point].x += TT_MULDIV( distance,
  1275.                                        v * 0x10000L,
  1276.                                        CUR.F_dot_P );
  1277.       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
  1278.     }
  1279.     v = CUR.GS.freeVector.y;
  1280.     if ( v != 0 )
  1281.     {
  1282.       zone->cur[point].y += TT_MULDIV( distance,
  1283.                                        v * 0x10000L,
  1284.                                        CUR.F_dot_P );
  1285.       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
  1286.     }
  1287.   }
  1288.   /*************************************************************************/
  1289.   /*                                                                       */
  1290.   /* <Function>                                                            */
  1291.   /*    Direct_Move_Orig                                                   */
  1292.   /*                                                                       */
  1293.   /* <Description>                                                         */
  1294.   /*    Moves the *original* position of a point by a given distance along */
  1295.   /*    the freedom vector.  Obviously, the point will not be `touched'.   */
  1296.   /*                                                                       */
  1297.   /* <Input>                                                               */
  1298.   /*    point    :: The index of the point to move.                        */
  1299.   /*                                                                       */
  1300.   /*    distance :: The distance to apply.                                 */
  1301.   /*                                                                       */
  1302.   /* <InOut>                                                               */
  1303.   /*    zone     :: The affected glyph zone.                               */
  1304.   /*                                                                       */
  1305.   static void
  1306.   Direct_Move_Orig( EXEC_OP_ TT_GlyphZone  zone,
  1307.                              FT_UShort     point,
  1308.                              FT_F26Dot6    distance )
  1309.   {
  1310.     FT_F26Dot6  v;
  1311. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  1312.     FT_ASSERT( !CUR.face->unpatented_hinting );
  1313. #endif
  1314.     v = CUR.GS.freeVector.x;
  1315.     if ( v != 0 )
  1316.       zone->org[point].x += TT_MULDIV( distance,
  1317.                                        v * 0x10000L,
  1318.                                        CUR.F_dot_P );
  1319.     v = CUR.GS.freeVector.y;
  1320.     if ( v != 0 )
  1321.       zone->org[point].y += TT_MULDIV( distance,
  1322.                                        v * 0x10000L,
  1323.                                        CUR.F_dot_P );
  1324.   }
  1325.   /*************************************************************************/
  1326.   /*                                                                       */
  1327.   /* Special versions of Direct_Move()                                     */
  1328.   /*                                                                       */
  1329.   /*   The following versions are used whenever both vectors are both      */
  1330.   /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */
  1331.   /*                                                                       */
  1332.   /*************************************************************************/
  1333.   static void
  1334.   Direct_Move_X( EXEC_OP_ TT_GlyphZone  zone,
  1335.                           FT_UShort     point,
  1336.                           FT_F26Dot6    distance )
  1337.   {
  1338.     FT_UNUSED_EXEC;
  1339.     zone->cur[point].x += distance;
  1340.     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_X;
  1341.   }
  1342.   static void
  1343.   Direct_Move_Y( EXEC_OP_ TT_GlyphZone  zone,
  1344.                           FT_UShort     point,
  1345.                           FT_F26Dot6    distance )
  1346.   {
  1347.     FT_UNUSED_EXEC;
  1348.     zone->cur[point].y += distance;
  1349.     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
  1350.   }
  1351.   /*************************************************************************/
  1352.   /*                                                                       */
  1353.   /* Special versions of Direct_Move_Orig()                                */
  1354.   /*                                                                       */
  1355.   /*   The following versions are used whenever both vectors are both      */
  1356.   /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */
  1357.   /*                                                                       */
  1358.   /*************************************************************************/
  1359.   static void
  1360.   Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone  zone,
  1361.                                FT_UShort     point,
  1362.                                FT_F26Dot6    distance )
  1363.   {
  1364.     FT_UNUSED_EXEC;
  1365.     zone->org[point].x += distance;
  1366.   }
  1367.   static void
  1368.   Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone  zone,
  1369.                                FT_UShort     point,
  1370.                                FT_F26Dot6    distance )
  1371.   {
  1372.     FT_UNUSED_EXEC;
  1373.     zone->org[point].y += distance;
  1374.   }
  1375.   /*************************************************************************/
  1376.   /*                                                                       */
  1377.   /* <Function>                                                            */
  1378.   /*    Round_None                                                         */
  1379.   /*                                                                       */
  1380.   /* <Description>                                                         */
  1381.   /*    Does not round, but adds engine compensation.                      */
  1382.   /*                                                                       */
  1383.   /* <Input>                                                               */
  1384.   /*    distance     :: The distance (not) to round.                       */
  1385.   /*                                                                       */
  1386.   /*    compensation :: The engine compensation.                           */
  1387.   /*                                                                       */
  1388.   /* <Return>                                                              */
  1389.   /*    The compensated distance.                                          */
  1390.   /*                                                                       */
  1391.   /* <Note>                                                                */
  1392.   /*    The TrueType specification says very few about the relationship    */
  1393.   /*    between rounding and engine compensation.  However, it seems from  */
  1394.   /*    the description of super round that we should add the compensation */
  1395.   /*    before rounding.                                                   */
  1396.   /*                                                                       */
  1397.   static FT_F26Dot6
  1398.   Round_None( EXEC_OP_ FT_F26Dot6  distance,
  1399.                        FT_F26Dot6  compensation )
  1400.   {
  1401.     FT_F26Dot6  val;
  1402.     FT_UNUSED_EXEC;
  1403.     if ( distance >= 0 )
  1404.     {
  1405.       val = distance + compensation;
  1406.       if ( distance && val < 0 )
  1407.         val = 0;
  1408.     }
  1409.     else {
  1410.       val = distance - compensation;
  1411.       if ( val > 0 )
  1412.         val = 0;
  1413.     }
  1414.     return val;
  1415.   }
  1416.   /*************************************************************************/
  1417.   /*                                                                       */
  1418.   /* <Function>                                                            */
  1419.   /*    Round_To_Grid                                                      */
  1420.   /*                                                                       */
  1421.   /* <Description>                                                         */
  1422.   /*    Rounds value to grid after adding engine compensation.             */
  1423.   /*                                                                       */
  1424.   /* <Input>                                                               */
  1425.   /*    distance     :: The distance to round.                             */
  1426.   /*                                                                       */
  1427.   /*    compensation :: The engine compensation.                           */
  1428.   /*                                                                       */
  1429.   /* <Return>                                                              */
  1430.   /*    Rounded distance.                                                  */
  1431.   /*                                                                       */
  1432.   static FT_F26Dot6
  1433.   Round_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
  1434.                           FT_F26Dot6  compensation )
  1435.   {
  1436.     FT_F26Dot6  val;
  1437.     FT_UNUSED_EXEC;
  1438.     if ( distance >= 0 )
  1439.     {
  1440.       val = distance + compensation + 32;
  1441.       if ( distance && val > 0 )
  1442.         val &= ~63;
  1443.       else
  1444.         val = 0;
  1445.     }
  1446.     else
  1447.     {
  1448.       val = -FT_PIX_ROUND( compensation - distance );
  1449.       if ( val > 0 )
  1450.         val = 0;
  1451.     }
  1452.     return  val;
  1453.   }
  1454.   /*************************************************************************/
  1455.   /*                                                                       */
  1456.   /* <Function>                                                            */
  1457.   /*    Round_To_Half_Grid                                                 */
  1458.   /*                                                                       */
  1459.   /* <Description>                                                         */
  1460.   /*    Rounds value to half grid after adding engine compensation.        */
  1461.   /*                                                                       */
  1462.   /* <Input>                                                               */
  1463.   /*    distance     :: The distance to round.                             */
  1464.   /*                                                                       */
  1465.   /*    compensation :: The engine compensation.                           */
  1466.   /*                                                                       */
  1467.   /* <Return>                                                              */
  1468.   /*    Rounded distance.                                                  */
  1469.   /*                                                                       */
  1470.   static FT_F26Dot6
  1471.   Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6  distance,
  1472.                                FT_F26Dot6  compensation )
  1473.   {
  1474.     FT_F26Dot6  val;
  1475.     FT_UNUSED_EXEC;
  1476.     if ( distance >= 0 )
  1477.     {
  1478.       val = FT_PIX_FLOOR( distance + compensation ) + 32;
  1479.       if ( distance && val < 0 )
  1480.         val = 0;
  1481.     }
  1482.     else
  1483.     {
  1484.       val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
  1485.       if ( val > 0 )
  1486.         val = 0;
  1487.     }
  1488.     return val;
  1489.   }
  1490.   /*************************************************************************/
  1491.   /*                                                                       */
  1492.   /* <Function>                                                            */
  1493.   /*    Round_Down_To_Grid                                                 */
  1494.   /*                                                                       */
  1495.   /* <Description>                                                         */
  1496.   /*    Rounds value down to grid after adding engine compensation.        */
  1497.   /*                                                                       */
  1498.   /* <Input>                                                               */
  1499.   /*    distance     :: The distance to round.                             */
  1500.   /*                                                                       */
  1501.   /*    compensation :: The engine compensation.                           */
  1502.   /*                                                                       */
  1503.   /* <Return>                                                              */
  1504.   /*    Rounded distance.                                                  */
  1505.   /*                                                                       */
  1506.   static FT_F26Dot6
  1507.   Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
  1508.                                FT_F26Dot6  compensation )
  1509.   {
  1510.     FT_F26Dot6  val;
  1511.     FT_UNUSED_EXEC;
  1512.     if ( distance >= 0 )
  1513.     {
  1514.       val = distance + compensation;
  1515.       if ( distance && val > 0 )
  1516.         val &= ~63;
  1517.       else
  1518.         val = 0;
  1519.     }
  1520.     else
  1521.     {
  1522.       val = -( ( compensation - distance ) & -64 );
  1523.       if ( val > 0 )
  1524.         val = 0;
  1525.     }
  1526.     return val;
  1527.   }
  1528.   /*************************************************************************/
  1529.   /*                                                                       */
  1530.   /* <Function>                                                            */
  1531.   /*    Round_Up_To_Grid                                                   */
  1532.   /*                                                                       */
  1533.   /* <Description>                                                         */
  1534.   /*    Rounds value up to grid after adding engine compensation.          */
  1535.   /*                                                                       */
  1536.   /* <Input>                                                               */
  1537.   /*    distance     :: The distance to round.                             */
  1538.   /*                                                                       */
  1539.   /*    compensation :: The engine compensation.                           */
  1540.   /*                                                                       */
  1541.   /* <Return>                                                              */
  1542.   /*    Rounded distance.                                                  */
  1543.   /*                                                                       */
  1544.   static FT_F26Dot6
  1545.   Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
  1546.                              FT_F26Dot6  compensation )
  1547.   {
  1548.     FT_F26Dot6  val;
  1549.     FT_UNUSED_EXEC;
  1550.     if ( distance >= 0 )
  1551.     {
  1552.       val = distance + compensation + 63;
  1553.       if ( distance && val > 0 )
  1554.         val &= ~63;
  1555.       else
  1556.         val = 0;
  1557.     }
  1558.     else
  1559.     {
  1560.       val = - FT_PIX_CEIL( compensation - distance );
  1561.       if ( val > 0 )
  1562.         val = 0;
  1563.     }
  1564.     return val;
  1565.   }
  1566.   /*************************************************************************/
  1567.   /*                                                                       */
  1568.   /* <Function>                                                            */
  1569.   /*    Round_To_Double_Grid                                               */
  1570.   /*                                                                       */
  1571.   /* <Description>                                                         */
  1572.   /*    Rounds value to double grid after adding engine compensation.      */
  1573.   /*                                                                       */
  1574.   /* <Input>                                                               */
  1575.   /*    distance     :: The distance to round.                             */
  1576.   /*                                                                       */
  1577.   /*    compensation :: The engine compensation.                           */
  1578.   /*                                                                       */
  1579.   /* <Return>                                                              */
  1580.   /*    Rounded distance.                                                  */
  1581.   /*                                                                       */
  1582.   static FT_F26Dot6
  1583.   Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6  distance,
  1584.                                  FT_F26Dot6  compensation )
  1585.   {
  1586.     FT_F26Dot6 val;
  1587.     FT_UNUSED_EXEC;
  1588.     if ( distance >= 0 )
  1589.     {
  1590.       val = distance + compensation + 16;
  1591.       if ( distance && val > 0 )
  1592.         val &= ~31;
  1593.       else
  1594.         val = 0;
  1595.     }
  1596.     else
  1597.     {
  1598.       val = -FT_PAD_ROUND( compensation - distance, 32 );
  1599.       if ( val > 0 )
  1600.         val = 0;
  1601.     }
  1602.     return val;
  1603.   }
  1604.   /*************************************************************************/
  1605.   /*                                                                       */
  1606.   /* <Function>                                                            */
  1607.   /*    Round_Super                                                        */
  1608.   /*                                                                       */
  1609.   /* <Description>                                                         */
  1610.   /*    Super-rounds value to grid after adding engine compensation.       */
  1611.   /*                                                                       */
  1612.   /* <Input>                                                               */
  1613.   /*    distance     :: The distance to round.                             */
  1614.   /*                                                                       */
  1615.   /*    compensation :: The engine compensation.                           */
  1616.   /*                                                                       */
  1617.   /* <Return>                                                              */
  1618.   /*    Rounded distance.                                                  */
  1619.   /*                                                                       */
  1620.   /* <Note>                                                                */
  1621.   /*    The TrueType specification says very few about the relationship    */
  1622.   /*    between rounding and engine compensation.  However, it seems from  */
  1623.   /*    the description of super round that we should add the compensation */
  1624.   /*    before rounding.                                                   */
  1625.   /*                                                                       */
  1626.   static FT_F26Dot6
  1627.   Round_Super( EXEC_OP_ FT_F26Dot6  distance,
  1628.                         FT_F26Dot6  compensation )
  1629.   {
  1630.     FT_F26Dot6  val;
  1631.     if ( distance >= 0 )
  1632.     {
  1633.       val = ( distance - CUR.phase + CUR.threshold + compensation ) &
  1634.               -CUR.period;
  1635.       if ( distance && val < 0 )
  1636.         val = 0;
  1637.       val += CUR.phase;
  1638.     }
  1639.     else
  1640.     {
  1641.       val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
  1642.                -CUR.period );
  1643.       if ( val > 0 )
  1644.         val = 0;
  1645.       val -= CUR.phase;
  1646.     }
  1647.     return val;
  1648.   }
  1649.   /*************************************************************************/
  1650.   /*                                                                       */
  1651.   /* <Function>                                                            */
  1652.   /*    Round_Super_45                                                     */
  1653.   /*                                                                       */
  1654.   /* <Description>                                                         */
  1655.   /*    Super-rounds value to grid after adding engine compensation.       */
  1656.   /*                                                                       */
  1657.   /* <Input>                                                               */
  1658.   /*    distance     :: The distance to round.                             */
  1659.   /*                                                                       */
  1660.   /*    compensation :: The engine compensation.                           */
  1661.   /*                                                                       */
  1662.   /* <Return>                                                              */
  1663.   /*    Rounded distance.                                                  */
  1664.   /*                                                                       */
  1665.   /* <Note>                                                                */
  1666.   /*    There is a separate function for Round_Super_45() as we may need   */
  1667.   /*    greater precision.                                                 */
  1668.   /*                                                                       */
  1669.   static FT_F26Dot6
  1670.   Round_Super_45( EXEC_OP_ FT_F26Dot6  distance,
  1671.                            FT_F26Dot6  compensation )
  1672.   {
  1673.     FT_F26Dot6  val;
  1674.     if ( distance >= 0 )
  1675.     {
  1676.       val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
  1677.                 CUR.period ) * CUR.period;
  1678.       if ( distance && val < 0 )
  1679.         val = 0;
  1680.       val += CUR.phase;
  1681.     }
  1682.     else
  1683.     {
  1684.       val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
  1685.                    CUR.period ) * CUR.period );
  1686.       if ( val > 0 )
  1687.         val = 0;
  1688.       val -= CUR.phase;
  1689.     }
  1690.     return val;
  1691.   }
  1692.   /*************************************************************************/
  1693.   /*                                                                       */
  1694.   /* <Function>                                                            */
  1695.   /*    Compute_Round                                                      */
  1696.   /*                                                                       */
  1697.   /* <Description>                                                         */
  1698.   /*    Sets the rounding mode.                                            */
  1699.   /*                                                                       */
  1700.   /* <Input>                                                               */
  1701.   /*    round_mode :: The rounding mode to be used.                        */
  1702.   /*                                                                       */
  1703.   static void
  1704.   Compute_Round( EXEC_OP_ FT_Byte  round_mode )
  1705.   {
  1706.     switch ( round_mode )
  1707.     {
  1708.     case TT_Round_Off:
  1709.       CUR.func_round = (TT_Round_Func)Round_None;
  1710.       break;
  1711.     case TT_Round_To_Grid:
  1712.       CUR.func_round = (TT_Round_Func)Round_To_Grid;
  1713.       break;
  1714.     case TT_Round_Up_To_Grid:
  1715.       CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
  1716.       break;
  1717.     case TT_Round_Down_To_Grid:
  1718.       CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
  1719.       break;
  1720.     case TT_Round_To_Half_Grid:
  1721.       CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
  1722.       break;
  1723.     case TT_Round_To_Double_Grid:
  1724.       CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
  1725.       break;
  1726.     case TT_Round_Super:
  1727.       CUR.func_round = (TT_Round_Func)Round_Super;
  1728.       break;
  1729.     case TT_Round_Super_45:
  1730.       CUR.func_round = (TT_Round_Func)Round_Super_45;
  1731.       break;
  1732.     }
  1733.   }
  1734.   /*************************************************************************/
  1735.   /*                                                                       */
  1736.   /* <Function>                                                            */
  1737.   /*    SetSuperRound                                                      */
  1738.   /*                                                                       */
  1739.   /* <Description>                                                         */
  1740.   /*    Sets Super Round parameters.                                       */
  1741.   /*                                                                       */
  1742.   /* <Input>                                                               */
  1743.   /*    GridPeriod :: Grid period                                          */
  1744.   /*    selector   :: SROUND opcode                                        */
  1745.   /*                                                                       */
  1746.   static void
  1747.   SetSuperRound( EXEC_OP_ FT_F26Dot6  GridPeriod,
  1748.                           FT_Long     selector )
  1749.   {
  1750.     switch ( (FT_Int)( selector & 0xC0 ) )
  1751.     {
  1752.       case 0:
  1753.         CUR.period = GridPeriod / 2;
  1754.         break;
  1755.       case 0x40:
  1756.         CUR.period = GridPeriod;
  1757.         break;
  1758.       case 0x80:
  1759.         CUR.period = GridPeriod * 2;
  1760.         break;
  1761.       /* This opcode is reserved, but... */
  1762.       case 0xC0:
  1763.         CUR.period = GridPeriod;
  1764.         break;
  1765.     }
  1766.     switch ( (FT_Int)( selector & 0x30 ) )
  1767.     {
  1768.     case 0:
  1769.       CUR.phase = 0;
  1770.       break;
  1771.     case 0x10:
  1772.       CUR.phase = CUR.period / 4;
  1773.       break;
  1774.     case 0x20:
  1775.       CUR.phase = CUR.period / 2;
  1776.       break;
  1777.     case 0x30:
  1778.       CUR.phase = CUR.period * 3 / 4;
  1779.       break;
  1780.     }
  1781.     if ( ( selector & 0x0F ) == 0 )
  1782.       CUR.threshold = CUR.period - 1;
  1783.     else
  1784.       CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
  1785.     CUR.period    /= 256;
  1786.     CUR.phase     /= 256;
  1787.     CUR.threshold /= 256;
  1788.   }
  1789.   /*************************************************************************/
  1790.   /*                                                                       */
  1791.   /* <Function>                                                            */
  1792.   /*    Project                                                            */
  1793.   /*                                                                       */
  1794.   /* <Description>                                                         */
  1795.   /*    Computes the projection of vector given by (v2-v1) along the       */
  1796.   /*    current projection vector.                                         */
  1797.   /*                                                                       */
  1798.   /* <Input>                                                               */
  1799.   /*    v1 :: First input vector.                                          */
  1800.   /*    v2 :: Second input vector.                                         */
  1801.   /*                                                                       */
  1802.   /* <Return>                                                              */
  1803.   /*    The distance in F26dot6 format.                                    */
  1804.   /*                                                                       */
  1805.   static FT_F26Dot6
  1806.   Project( EXEC_OP_ FT_Pos  dx,
  1807.                     FT_Pos  dy )
  1808.   {
  1809. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  1810.     FT_ASSERT( !CUR.face->unpatented_hinting );
  1811. #endif
  1812.     return TT_DotFix14( dx, dy,
  1813.                         CUR.GS.projVector.x,
  1814.                         CUR.GS.projVector.y );
  1815.   }
  1816.   /*************************************************************************/
  1817.   /*                                                                       */
  1818.   /* <Function>                                                            */
  1819.   /*    Dual_Project                                                       */
  1820.   /*                                                                       */
  1821.   /* <Description>                                                         */
  1822.   /*    Computes the projection of the vector given by (v2-v1) along the   */
  1823.   /*    current dual vector.                                               */
  1824.   /*                                                                       */
  1825.   /* <Input>                                                               */
  1826.   /*    v1 :: First input vector.                                          */
  1827.   /*    v2 :: Second input vector.                                         */
  1828.   /*                                                                       */
  1829.   /* <Return>                                                              */
  1830.   /*    The distance in F26dot6 format.                                    */
  1831.   /*                                                                       */
  1832.   static FT_F26Dot6
  1833.   Dual_Project( EXEC_OP_ FT_Pos  dx,
  1834.                          FT_Pos  dy )
  1835.   {
  1836.     return TT_DotFix14( dx, dy,
  1837.                         CUR.GS.dualVector.x,
  1838.                         CUR.GS.dualVector.y );
  1839.   }
  1840.   /*************************************************************************/
  1841.   /*                                                                       */
  1842.   /* <Function>                                                            */
  1843.   /*    Project_x                                                          */
  1844.   /*                                                                       */
  1845.   /* <Description>                                                         */
  1846.   /*    Computes the projection of the vector given by (v2-v1) along the   */
  1847.   /*    horizontal axis.                                                   */
  1848.   /*                                                                       */
  1849.   /* <Input>                                                               */
  1850.   /*    v1 :: First input vector.                                          */
  1851.   /*    v2 :: Second input vector.                                         */
  1852.   /*                                                                       */
  1853.   /* <Return>                                                              */
  1854.   /*    The distance in F26dot6 format.                                    */
  1855.   /*                                                                       */
  1856.   static FT_F26Dot6
  1857.   Project_x( EXEC_OP_ FT_Pos  dx,
  1858.                       FT_Pos  dy )
  1859.   {
  1860.     FT_UNUSED_EXEC;
  1861.     FT_UNUSED( dy );
  1862.     return dx;
  1863.   }
  1864.   /*************************************************************************/
  1865.   /*                                                                       */
  1866.   /* <Function>                                                            */
  1867.   /*    Project_y                                                          */
  1868.   /*                                                                       */
  1869.   /* <Description>                                                         */
  1870.   /*    Computes the projection of the vector given by (v2-v1) along the   */
  1871.   /*    vertical axis.                                                     */
  1872.   /*                                                                       */
  1873.   /* <Input>                                                               */
  1874.   /*    v1 :: First input vector.                                          */
  1875.   /*    v2 :: Second input vector.                                         */
  1876.   /*                                                                       */
  1877.   /* <Return>                                                              */
  1878.   /*    The distance in F26dot6 format.                                    */
  1879.   /*                                                                       */
  1880.   static FT_F26Dot6
  1881.   Project_y( EXEC_OP_ FT_Pos  dx,
  1882.                       FT_Pos  dy )
  1883.   {
  1884.     FT_UNUSED_EXEC;
  1885.     FT_UNUSED( dx );
  1886.     return dy;
  1887.   }
  1888.   /*************************************************************************/
  1889.   /*                                                                       */
  1890.   /* <Function>                                                            */
  1891.   /*    Compute_Funcs                                                      */
  1892.   /*                                                                       */
  1893.   /* <Description>                                                         */
  1894.   /*    Computes the projection and movement function pointers according   */
  1895.   /*    to the current graphics state.                                     */
  1896.   /*                                                                       */
  1897.   static void
  1898.   Compute_Funcs( EXEC_OP )
  1899.   {
  1900. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  1901.     if ( CUR.face->unpatented_hinting )
  1902.     {
  1903.       /* If both vectors point rightwards along the x axis, set             */
  1904.       /* `both-x-axis' true, otherwise set it false.  The x values only     */
  1905.       /* need be tested because the vector has been normalised to a unit    */
  1906.       /* vector of length 0x4000 = unity.                                   */
  1907.       CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
  1908.                                       CUR.GS.freeVector.x == 0x4000 );
  1909.       /* Throw away projection and freedom vector information */
  1910.       /* because the patents don't allow them to be stored.   */
  1911.       /* The relevant US Patents are 5155805 and 5325479.     */
  1912.       CUR.GS.projVector.x = 0;
  1913.       CUR.GS.projVector.y = 0;
  1914.       CUR.GS.freeVector.x = 0;
  1915.       CUR.GS.freeVector.y = 0;
  1916.       if ( CUR.GS.both_x_axis )
  1917.       {
  1918.         CUR.func_project   = Project_x;
  1919.         CUR.func_move      = Direct_Move_X;
  1920.         CUR.func_move_orig = Direct_Move_Orig_X;
  1921.       }
  1922.       else
  1923.       {
  1924.         CUR.func_project   = Project_y;
  1925.         CUR.func_move      = Direct_Move_Y;
  1926.         CUR.func_move_orig = Direct_Move_Orig_Y;
  1927.       }
  1928.       if ( CUR.GS.dualVector.x == 0x4000 )
  1929.         CUR.func_dualproj = Project_x;
  1930.       else
  1931.       {
  1932.         if ( CUR.GS.dualVector.y == 0x4000 )
  1933.           CUR.func_dualproj = Project_y;
  1934.         else
  1935.           CUR.func_dualproj = Dual_Project;
  1936.       }
  1937.       /* Force recalculation of cached aspect ratio */
  1938.       CUR.tt_metrics.ratio = 0;
  1939.       return;
  1940.     }
  1941. #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
  1942.     if ( CUR.GS.freeVector.x == 0x4000 )
  1943.       CUR.F_dot_P       = CUR.GS.projVector.x * 0x10000L;
  1944.     else
  1945.     {
  1946.       if ( CUR.GS.freeVector.y == 0x4000 )
  1947.         CUR.F_dot_P       = CUR.GS.projVector.y * 0x10000L;
  1948.       else
  1949.         CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 +
  1950.                       (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;
  1951.     }
  1952.     if ( CUR.GS.projVector.x == 0x4000 )
  1953.       CUR.func_project = (TT_Project_Func)Project_x;
  1954.     else
  1955.     {
  1956.       if ( CUR.GS.projVector.y == 0x4000 )
  1957.         CUR.func_project = (TT_Project_Func)Project_y;
  1958.       else
  1959.         CUR.func_project = (TT_Project_Func)Project;
  1960.     }
  1961.     if ( CUR.GS.dualVector.x == 0x4000 )
  1962.       CUR.func_dualproj = (TT_Project_Func)Project_x;
  1963.     else
  1964.     {
  1965.       if ( CUR.GS.dualVector.y == 0x4000 )
  1966.         CUR.func_dualproj = (TT_Project_Func)Project_y;
  1967.       else
  1968.         CUR.func_dualproj = (TT_Project_Func)Dual_Project;
  1969.     }
  1970.     CUR.func_move      = (TT_Move_Func)Direct_Move;
  1971.     CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
  1972.     if ( CUR.F_dot_P == 0x40000000L )
  1973.     {
  1974.       if ( CUR.GS.freeVector.x == 0x4000 )
  1975.       {
  1976.         CUR.func_move      = (TT_Move_Func)Direct_Move_X;
  1977.         CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
  1978.       }
  1979.       else
  1980.       {
  1981.         if ( CUR.GS.freeVector.y == 0x4000 )
  1982.         {
  1983.           CUR.func_move      = (TT_Move_Func)Direct_Move_Y;
  1984.           CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
  1985.         }
  1986.       }
  1987.     }
  1988.     /* at small sizes, F_dot_P can become too small, resulting   */
  1989.     /* in overflows and `spikes' in a number of glyphs like `w'. */
  1990.     if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L )
  1991.       CUR.F_dot_P = 0x40000000L;
  1992.     /* Disable cached aspect ratio */
  1993.     CUR.tt_metrics.ratio = 0;
  1994.   }
  1995.   /*************************************************************************/
  1996.   /*                                                                       */
  1997.   /* <Function>                                                            */
  1998.   /*    Normalize                                                          */
  1999.   /*                                                                       */
  2000.   /* <Description>                                                         */
  2001.   /*    Norms a vector.                                                    */
  2002.   /*                                                                       */
  2003.   /* <Input>                                                               */
  2004.   /*    Vx :: The horizontal input vector coordinate.                      */
  2005.   /*    Vy :: The vertical input vector coordinate.                        */
  2006.   /*                                                                       */
  2007.   /* <Output>                                                              */
  2008.   /*    R  :: The normed unit vector.                                      */
  2009.   /*                                                                       */
  2010.   /* <Return>                                                              */
  2011.   /*    Returns FAILURE if a vector parameter is zero.                     */
  2012.   /*                                                                       */
  2013.   /* <Note>                                                                */
  2014.   /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */
  2015.   /*    R is undefined.                                                    */
  2016.   /*                                                                       */
  2017.   static FT_Bool
  2018.   Normalize( EXEC_OP_ FT_F26Dot6      Vx,
  2019.                       FT_F26Dot6      Vy,
  2020.                       FT_UnitVector*  R )
  2021.   {
  2022.     FT_F26Dot6  W;
  2023.     FT_Bool     S1, S2;
  2024.     FT_UNUSED_EXEC;
  2025.     if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L )
  2026.     {
  2027.       Vx *= 0x100;
  2028.       Vy *= 0x100;
  2029.       W = TT_VecLen( Vx, Vy );
  2030.       if ( W == 0 )
  2031.       {
  2032.         /* XXX: UNDOCUMENTED! It seems that it is possible to try   */
  2033.         /*      to normalize the vector (0,0).  Return immediately. */
  2034.         return SUCCESS;
  2035.       }
  2036.       R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W );
  2037.       R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W );
  2038.       return SUCCESS;
  2039.     }
  2040.     W = TT_VecLen( Vx, Vy );
  2041.     Vx = FT_MulDiv( Vx, 0x4000L, W );
  2042.     Vy = FT_MulDiv( Vy, 0x4000L, W );
  2043.     W = Vx * Vx + Vy * Vy;
  2044.     /* Now, we want that Sqrt( W ) = 0x4000 */
  2045.     /* Or 0x10000000 <= W < 0x10004000        */
  2046.     if ( Vx < 0 )
  2047.     {
  2048.       Vx = -Vx;
  2049.       S1 = TRUE;
  2050.     }
  2051.     else
  2052.       S1 = FALSE;
  2053.     if ( Vy < 0 )
  2054.     {
  2055.       Vy = -Vy;
  2056.       S2 = TRUE;
  2057.     }
  2058.     else
  2059.       S2 = FALSE;
  2060.     while ( W < 0x10000000L )
  2061.     {
  2062.       /* We need to increase W by a minimal amount */
  2063.       if ( Vx < Vy )
  2064.         Vx++;
  2065.       else
  2066.         Vy++;
  2067.       W = Vx * Vx + Vy * Vy;
  2068.     }
  2069.     while ( W >= 0x10004000L )
  2070.     {
  2071.       /* We need to decrease W by a minimal amount */
  2072.       if ( Vx < Vy )
  2073.         Vx--;
  2074.       else
  2075.         Vy--;
  2076.       W = Vx * Vx + Vy * Vy;
  2077.     }
  2078.     /* Note that in various cases, we can only  */
  2079.     /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */
  2080.     if ( S1 )
  2081.       Vx = -Vx;
  2082.     if ( S2 )
  2083.       Vy = -Vy;
  2084.     R->x = (FT_F2Dot14)Vx;   /* Type conversion */
  2085.     R->y = (FT_F2Dot14)Vy;   /* Type conversion */
  2086.     return SUCCESS;
  2087.   }
  2088.   /*************************************************************************/
  2089.   /*                                                                       */
  2090.   /* Here we start with the implementation of the various opcodes.         */
  2091.   /*                                                                       */
  2092.   /*************************************************************************/
  2093.   static FT_Bool
  2094.   Ins_SxVTL( EXEC_OP_ FT_UShort       aIdx1,
  2095.                       FT_UShort       aIdx2,
  2096.                       FT_Int          aOpc,
  2097.                       FT_UnitVector*  Vec )
  2098.   {
  2099.     FT_Long     A, B, C;
  2100.     FT_Vector*  p1;
  2101.     FT_Vector*  p2;
  2102.     if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
  2103.          BOUNDS( aIdx2, CUR.zp1.n_points ) )
  2104.     {
  2105.       if ( CUR.pedantic_hinting )
  2106.         CUR.error = TT_Err_Invalid_Reference;
  2107.       return FAILURE;
  2108.     }
  2109.     p1 = CUR.zp1.cur + aIdx2;
  2110.     p2 = CUR.zp2.cur + aIdx1;
  2111.     A = p1->x - p2->x;
  2112.     B = p1->y - p2->y;
  2113.     if ( ( aOpc & 1 ) != 0 )
  2114.     {
  2115.       C =  B;   /* counter clockwise rotation */
  2116.       B =  A;
  2117.       A = -C;
  2118.     }
  2119.     NORMalize( A, B, Vec );
  2120.     return SUCCESS;
  2121.   }
  2122.   /* When not using the big switch statements, the interpreter uses a */
  2123.   /* call table defined later below in this source.  Each opcode must */
  2124.   /* thus have a corresponding function, even trivial ones.           */
  2125.   /*                                                                  */
  2126.   /* They are all defined there.                                      */
  2127. #define DO_SVTCA                            
  2128.   {                                         
  2129.     FT_Short  A, B;                         
  2130.                                             
  2131.                                             
  2132.     A = (FT_Short)( CUR.opcode & 1 ) << 14; 
  2133.     B = A ^ (FT_Short)0x4000;               
  2134.                                             
  2135.     CUR.GS.freeVector.x = A;                
  2136.     CUR.GS.projVector.x = A;                
  2137.     CUR.GS.dualVector.x = A;                
  2138.                                             
  2139.     CUR.GS.freeVector.y = B;                
  2140.     CUR.GS.projVector.y = B;                
  2141.     CUR.GS.dualVector.y = B;                
  2142.                                             
  2143.     COMPUTE_Funcs();                        
  2144.   }
  2145. #define DO_SPVTCA                           
  2146.   {                                         
  2147.     FT_Short  A, B;                         
  2148.                                             
  2149.                                             
  2150.     A = (FT_Short)( CUR.opcode & 1 ) << 14; 
  2151.     B = A ^ (FT_Short)0x4000;               
  2152.                                             
  2153.     CUR.GS.projVector.x = A;                
  2154.     CUR.GS.dualVector.x = A;                
  2155.                                             
  2156.     CUR.GS.projVector.y = B;                
  2157.     CUR.GS.dualVector.y = B;                
  2158.                                             
  2159.     GUESS_VECTOR( freeVector );             
  2160.                                             
  2161.     COMPUTE_Funcs();                        
  2162.   }
  2163. #define DO_SFVTCA                           
  2164.   {                                         
  2165.     FT_Short  A, B;                         
  2166.                                             
  2167.                                             
  2168.     A = (FT_Short)( CUR.opcode & 1 ) << 14; 
  2169.     B = A ^ (FT_Short)0x4000;               
  2170.                                             
  2171.     CUR.GS.freeVector.x = A;                
  2172.     CUR.GS.freeVector.y = B;                
  2173.                                             
  2174.     GUESS_VECTOR( projVector );             
  2175.                                             
  2176.     COMPUTE_Funcs();                        
  2177.   }
  2178. #define DO_SPVTL                                      
  2179.     if ( INS_SxVTL( (FT_UShort)args[1],               
  2180.                     (FT_UShort)args[0],               
  2181.                     CUR.opcode,                       
  2182.                     &CUR.GS.projVector ) == SUCCESS ) 
  2183.     {                                                 
  2184.       CUR.GS.dualVector = CUR.GS.projVector;          
  2185.       GUESS_VECTOR( freeVector );                     
  2186.       COMPUTE_Funcs();                                
  2187.     }
  2188. #define DO_SFVTL                                      
  2189.     if ( INS_SxVTL( (FT_UShort)args[1],               
  2190.                     (FT_UShort)args[0],               
  2191.                     CUR.opcode,                       
  2192.                     &CUR.GS.freeVector ) == SUCCESS ) 
  2193.     {                                                 
  2194.       GUESS_VECTOR( projVector );                     
  2195.       COMPUTE_Funcs();                                
  2196.     }
  2197. #define DO_SFVTPV                          
  2198.     GUESS_VECTOR( projVector );            
  2199.     CUR.GS.freeVector = CUR.GS.projVector; 
  2200.     COMPUTE_Funcs();
  2201. #define DO_SPVFS                                
  2202.   {                                             
  2203.     FT_Short  S;                                
  2204.     FT_Long   X, Y;                             
  2205.                                                 
  2206.                                                 
  2207.     /* Only use low 16bits, then sign extend */ 
  2208.     S = (FT_Short)args[1];                      
  2209.     Y = (FT_Long)S;                             
  2210.     S = (FT_Short)args[0];                      
  2211.     X = (FT_Long)S;                             
  2212.                                                 
  2213.     NORMalize( X, Y, &CUR.GS.projVector );      
  2214.                                                 
  2215.     CUR.GS.dualVector = CUR.GS.projVector;      
  2216.     GUESS_VECTOR( freeVector );                 
  2217.     COMPUTE_Funcs();                            
  2218.   }
  2219. #define DO_SFVFS                                
  2220.   {                                             
  2221.     FT_Short  S;                                
  2222.     FT_Long   X, Y;                             
  2223.                                                 
  2224.                                                 
  2225.     /* Only use low 16bits, then sign extend */ 
  2226.     S = (FT_Short)args[1];                      
  2227.     Y = (FT_Long)S;                             
  2228.     S = (FT_Short)args[0];                      
  2229.     X = S;                                      
  2230.                                                 
  2231.     NORMalize( X, Y, &CUR.GS.freeVector );      
  2232.     GUESS_VECTOR( projVector );                 
  2233.     COMPUTE_Funcs();                            
  2234.   }
  2235. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  2236. #define DO_GPV                                   
  2237.     if ( CUR.face->unpatented_hinting )          
  2238.     {                                            
  2239.       args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; 
  2240.       args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; 
  2241.     }                                            
  2242.     else                                         
  2243.     {                                            
  2244.       args[0] = CUR.GS.projVector.x;             
  2245.       args[1] = CUR.GS.projVector.y;             
  2246.     }
  2247. #else
  2248. #define DO_GPV                                   
  2249.     args[0] = CUR.GS.projVector.x;               
  2250.     args[1] = CUR.GS.projVector.y;
  2251. #endif
  2252. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  2253. #define DO_GFV                                   
  2254.     if ( CUR.face->unpatented_hinting )          
  2255.     {                                            
  2256.       args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; 
  2257.       args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; 
  2258.     }                                            
  2259.     else                                         
  2260.     {                                            
  2261.       args[0] = CUR.GS.freeVector.x;             
  2262.       args[1] = CUR.GS.freeVector.y;             
  2263.     }
  2264. #else
  2265. #define DO_GFV                                   
  2266.     args[0] = CUR.GS.freeVector.x;               
  2267.     args[1] = CUR.GS.freeVector.y;
  2268. #endif
  2269. #define DO_SRP0                      
  2270.     CUR.GS.rp0 = (FT_UShort)args[0];
  2271. #define DO_SRP1                      
  2272.     CUR.GS.rp1 = (FT_UShort)args[0];
  2273. #define DO_SRP2                      
  2274.     CUR.GS.rp2 = (FT_UShort)args[0];
  2275. #define DO_RTHG                                         
  2276.     CUR.GS.round_state = TT_Round_To_Half_Grid;         
  2277.     CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
  2278. #define DO_RTG                                     
  2279.     CUR.GS.round_state = TT_Round_To_Grid;         
  2280.     CUR.func_round = (TT_Round_Func)Round_To_Grid;
  2281. #define DO_RTDG                                           
  2282.     CUR.GS.round_state = TT_Round_To_Double_Grid;         
  2283.     CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
  2284. #define DO_RUTG                                       
  2285.     CUR.GS.round_state = TT_Round_Up_To_Grid;         
  2286.     CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
  2287. #define DO_RDTG                                         
  2288.     CUR.GS.round_state = TT_Round_Down_To_Grid;         
  2289.     CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
  2290. #define DO_ROFF                                 
  2291.     CUR.GS.round_state = TT_Round_Off;          
  2292.     CUR.func_round = (TT_Round_Func)Round_None;
  2293. #define DO_SROUND                                
  2294.     SET_SuperRound( 0x4000, args[0] );           
  2295.     CUR.GS.round_state = TT_Round_Super;         
  2296.     CUR.func_round = (TT_Round_Func)Round_Super;
  2297. #define DO_S45ROUND                                 
  2298.     SET_SuperRound( 0x2D41, args[0] );              
  2299.     CUR.GS.round_state = TT_Round_Super_45;         
  2300.     CUR.func_round = (TT_Round_Func)Round_Super_45;
  2301. #define DO_SLOOP                       
  2302.     if ( args[0] < 0 )                 
  2303.       CUR.error = TT_Err_Bad_Argument; 
  2304.     else                               
  2305.       CUR.GS.loop = args[0];
  2306. #define DO_SMD                         
  2307.     CUR.GS.minimum_distance = args[0];
  2308. #define DO_SCVTCI                                     
  2309.     CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
  2310. #define DO_SSWCI                                     
  2311.     CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
  2312.     /* XXX: UNDOCUMENTED! or bug in the Windows engine?   */
  2313.     /*                                                    */
  2314.     /*      It seems that the value that is read here is  */
  2315.     /*      expressed in 16.16 format rather than in font */
  2316.     /*      units.                                        */
  2317.     /*                                                    */
  2318. #define DO_SSW                                                 
  2319.     CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 );
  2320. #define DO_FLIPON            
  2321.     CUR.GS.auto_flip = TRUE;
  2322. #define DO_FLIPOFF            
  2323.     CUR.GS.auto_flip = FALSE;
  2324. #define DO_SDB                             
  2325.     CUR.GS.delta_base = (FT_Short)args[0];
  2326. #define DO_SDS                              
  2327.     CUR.GS.delta_shift = (FT_Short)args[0];
  2328. #define DO_MD  /* nothing */
  2329. #define DO_MPPEM              
  2330.     args[0] = CURRENT_Ppem();
  2331.   /* Note: The pointSize should be irrelevant in a given font program; */
  2332.   /*       we thus decide to return only the ppem.                     */
  2333. #if 0
  2334. #define DO_MPS                       
  2335.     args[0] = CUR.metrics.pointSize;
  2336. #else
  2337. #define DO_MPS                
  2338.     args[0] = CURRENT_Ppem();
  2339. #endif /* 0 */
  2340. #define DO_DUP         
  2341.     args[1] = args[0];
  2342. #define DO_CLEAR     
  2343.     CUR.new_top = 0;
  2344. #define DO_SWAP        
  2345.   {                    
  2346.     FT_Long  L;        
  2347.                        
  2348.                        
  2349.     L       = args[0]; 
  2350.     args[0] = args[1]; 
  2351.     args[1] = L;       
  2352.   }
  2353. #define DO_DEPTH       
  2354.     args[0] = CUR.top;
  2355. #define DO_CINDEX                           
  2356.   {                                         
  2357.     FT_Long  L;                             
  2358.                                             
  2359.                                             
  2360.     L = args[0];                            
  2361.                                             
  2362.     if ( L <= 0 || L > CUR.args )           
  2363.       CUR.error = TT_Err_Invalid_Reference; 
  2364.     else                                    
  2365.       args[0] = CUR.stack[CUR.args - L];    
  2366.   }
  2367. #define DO_JROT               
  2368.     if ( args[1] != 0 )       
  2369.     {                         
  2370.       CUR.IP      += args[0]; 
  2371.       CUR.step_ins = FALSE;   
  2372.     }
  2373. #define DO_JMPR             
  2374.     CUR.IP      += args[0]; 
  2375.     CUR.step_ins = FALSE;
  2376. #define DO_JROF               
  2377.     if ( args[1] == 0 )       
  2378.     {                         
  2379.       CUR.IP      += args[0]; 
  2380.       CUR.step_ins = FALSE;   
  2381.     }
  2382. #define DO_LT                        
  2383.     args[0] = ( args[0] < args[1] );
  2384. #define DO_LTEQ                       
  2385.     args[0] = ( args[0] <= args[1] );
  2386. #define DO_GT                        
  2387.     args[0] = ( args[0] > args[1] );
  2388. #define DO_GTEQ                       
  2389.     args[0] = ( args[0] >= args[1] );
  2390. #define DO_EQ                         
  2391.     args[0] = ( args[0] == args[1] );
  2392. #define DO_NEQ                        
  2393.     args[0] = ( args[0] != args[1] );
  2394. #define DO_ODD                                                  
  2395.     args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
  2396. #define DO_EVEN                                                
  2397.     args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
  2398. #define DO_AND                        
  2399.     args[0] = ( args[0] && args[1] );
  2400. #define DO_OR                         
  2401.     args[0] = ( args[0] || args[1] );
  2402. #define DO_NOT          
  2403.     args[0] = !args[0];
  2404. #define DO_ADD          
  2405.     args[0] += args[1];
  2406. #define DO_SUB          
  2407.     args[0] -= args[1];
  2408. #define DO_DIV                                               
  2409.     if ( args[1] == 0 )                                      
  2410.       CUR.error = TT_Err_Divide_By_Zero;                     
  2411.     else                                                     
  2412.       args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] );
  2413. #define DO_MUL                                    
  2414.     args[0] = TT_MULDIV( args[0], args[1], 64L );
  2415. #define DO_ABS                   
  2416.     args[0] = FT_ABS( args[0] );
  2417. #define DO_NEG          
  2418.     args[0] = -args[0];
  2419. #define DO_FLOOR    
  2420.     args[0] = FT_PIX_FLOOR( args[0] );
  2421. #define DO_CEILING                    
  2422.     args[0] = FT_PIX_CEIL( args[0] );
  2423. #define DO_RS                          
  2424.    {                                   
  2425.      FT_ULong  I = (FT_ULong)args[0];  
  2426.                                        
  2427.                                        
  2428.      if ( BOUNDS( I, CUR.storeSize ) ) 
  2429.      {                                 
  2430.        if ( CUR.pedantic_hinting )     
  2431.        {                               
  2432.          ARRAY_BOUND_ERROR;            
  2433.        }                               
  2434.        else                            
  2435.          args[0] = 0;                  
  2436.      }                                 
  2437.      else                              
  2438.        args[0] = CUR.storage[I];       
  2439.    }
  2440. #define DO_WS                          
  2441.    {                                   
  2442.      FT_ULong  I = (FT_ULong)args[0];  
  2443.                                        
  2444.                                        
  2445.      if ( BOUNDS( I, CUR.storeSize ) ) 
  2446.      {                                 
  2447.        if ( CUR.pedantic_hinting )     
  2448.        {                               
  2449.          ARRAY_BOUND_ERROR;            
  2450.        }                               
  2451.      }                                 
  2452.      else                              
  2453.        CUR.storage[I] = args[1];       
  2454.    }
  2455. #define DO_RCVT                          
  2456.    {                                     
  2457.      FT_ULong  I = (FT_ULong)args[0];    
  2458.                                          
  2459.                                          
  2460.      if ( BOUNDS( I, CUR.cvtSize ) )     
  2461.      {                                   
  2462.        if ( CUR.pedantic_hinting )       
  2463.        {                                 
  2464.          ARRAY_BOUND_ERROR;              
  2465.        }                                 
  2466.        else                              
  2467.          args[0] = 0;                    
  2468.      }                                   
  2469.      else                                
  2470.        args[0] = CUR_Func_read_cvt( I ); 
  2471.    }
  2472. #define DO_WCVTP                         
  2473.    {                                     
  2474.      FT_ULong  I = (FT_ULong)args[0];    
  2475.                                          
  2476.                                          
  2477.      if ( BOUNDS( I, CUR.cvtSize ) )     
  2478.      {                                   
  2479.        if ( CUR.pedantic_hinting )       
  2480.        {                                 
  2481.          ARRAY_BOUND_ERROR;              
  2482.        }                                 
  2483.      }                                   
  2484.      else                                
  2485.        CUR_Func_write_cvt( I, args[1] ); 
  2486.    }
  2487. #define DO_WCVTF                                                
  2488.    {                                                            
  2489.      FT_ULong  I = (FT_ULong)args[0];                           
  2490.                                                                 
  2491.                                                                 
  2492.      if ( BOUNDS( I, CUR.cvtSize ) )                            
  2493.      {                                                          
  2494.        if ( CUR.pedantic_hinting )                              
  2495.        {                                                        
  2496.          ARRAY_BOUND_ERROR;                                     
  2497.        }                                                        
  2498.      }                                                          
  2499.      else                                                       
  2500.        CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); 
  2501.    }
  2502. #define DO_DEBUG                     
  2503.     CUR.error = TT_Err_Debug_OpCode;
  2504. #define DO_ROUND                                                   
  2505.     args[0] = CUR_Func_round(                                      
  2506.                 args[0],                                           
  2507.                 CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
  2508. #define DO_NROUND                                                            
  2509.     args[0] = ROUND_None( args[0],                                           
  2510.                           CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
  2511. #define DO_MAX               
  2512.     if ( args[1] > args[0] ) 
  2513.       args[0] = args[1];
  2514. #define DO_MIN               
  2515.     if ( args[1] < args[0] ) 
  2516.       args[0] = args[1];
  2517. #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
  2518. #undef  ARRAY_BOUND_ERROR
  2519. #define ARRAY_BOUND_ERROR                   
  2520.     {                                       
  2521.       CUR.error = TT_Err_Invalid_Reference; 
  2522.       return;                               
  2523.     }
  2524.   /*************************************************************************/
  2525.   /*                                                                       */
  2526.   /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
  2527.   /* Opcode range: 0x00-0x01                                               */
  2528.   /* Stack:        -->                                                     */
  2529.   /*                                                                       */
  2530.   static void
  2531.   Ins_SVTCA( INS_ARG )
  2532.   {
  2533.     DO_SVTCA
  2534.   }
  2535.   /*************************************************************************/
  2536.   /*                                                                       */
  2537.   /* SPVTCA[a]:    Set PVector to Coordinate Axis                          */
  2538.   /* Opcode range: 0x02-0x03                                               */
  2539.   /* Stack:        -->                                                     */
  2540.   /*                                                                       */
  2541.   static void
  2542.   Ins_SPVTCA( INS_ARG )
  2543.   {
  2544.     DO_SPVTCA
  2545.   }
  2546.   /*************************************************************************/
  2547.   /*                                                                       */
  2548.   /* SFVTCA[a]:    Set FVector to Coordinate Axis                          */
  2549.   /* Opcode range: 0x04-0x05                                               */
  2550.   /* Stack:        -->                                                     */
  2551.   /*                                                                       */
  2552.   static void
  2553.   Ins_SFVTCA( INS_ARG )
  2554.   {
  2555.     DO_SFVTCA
  2556.   }
  2557.   /*************************************************************************/
  2558.   /*                                                                       */
  2559.   /* SPVTL[a]:     Set PVector To Line                                     */
  2560.   /* Opcode range: 0x06-0x07                                               */
  2561.   /* Stack:        uint32 uint32 -->                                       */
  2562.   /*                                                                       */
  2563.   static void
  2564.   Ins_SPVTL( INS_ARG )
  2565.   {
  2566.     DO_SPVTL
  2567.   }
  2568.   /*************************************************************************/
  2569.   /*                                                                       */
  2570.   /* SFVTL[a]:     Set FVector To Line                                     */
  2571.   /* Opcode range: 0x08-0x09                                               */
  2572.   /* Stack:        uint32 uint32 -->                                       */
  2573.   /*                                                                       */
  2574.   static void
  2575.   Ins_SFVTL( INS_ARG )
  2576.   {
  2577.     DO_SFVTL
  2578.   }
  2579.   /*************************************************************************/
  2580.   /*                                                                       */
  2581.   /* SFVTPV[]:     Set FVector To PVector                                  */
  2582.   /* Opcode range: 0x0E                                                    */
  2583.   /* Stack:        -->                                                     */
  2584.   /*                                                                       */
  2585.   static void
  2586.   Ins_SFVTPV( INS_ARG )
  2587.   {
  2588.     DO_SFVTPV
  2589.   }
  2590.   /*************************************************************************/
  2591.   /*                                                                       */
  2592.   /* SPVFS[]:      Set PVector From Stack                                  */
  2593.   /* Opcode range: 0x0A                                                    */
  2594.   /* Stack:        f2.14 f2.14 -->                                         */
  2595.   /*                                                                       */
  2596.   static void
  2597.   Ins_SPVFS( INS_ARG )
  2598.   {
  2599.     DO_SPVFS
  2600.   }
  2601.   /*************************************************************************/
  2602.   /*                                                                       */
  2603.   /* SFVFS[]:      Set FVector From Stack                                  */
  2604.   /* Opcode range: 0x0B                                                    */
  2605.   /* Stack:        f2.14 f2.14 -->                                         */
  2606.   /*                                                                       */
  2607.   static void
  2608.   Ins_SFVFS( INS_ARG )
  2609.   {
  2610.     DO_SFVFS
  2611.   }
  2612.   /*************************************************************************/
  2613.   /*                                                                       */
  2614.   /* GPV[]:        Get Projection Vector                                   */
  2615.   /* Opcode range: 0x0C                                                    */
  2616.   /* Stack:        ef2.14 --> ef2.14                                       */
  2617.   /*                                                                       */
  2618.   static void
  2619.   Ins_GPV( INS_ARG )
  2620.   {
  2621.     DO_GPV
  2622.   }
  2623.   /*************************************************************************/
  2624.   /* GFV[]:        Get Freedom Vector                                      */
  2625.   /* Opcode range: 0x0D                                                    */
  2626.   /* Stack:        ef2.14 --> ef2.14                                       */
  2627.   /*                                                                       */
  2628.   static void
  2629.   Ins_GFV( INS_ARG )
  2630.   {
  2631.     DO_GFV
  2632.   }
  2633.   /*************************************************************************/
  2634.   /*                                                                       */
  2635.   /* SRP0[]:       Set Reference Point 0                                   */
  2636.   /* Opcode range: 0x10                                                    */
  2637.   /* Stack:        uint32 -->                                              */
  2638.   /*                                                                       */
  2639.   static void
  2640.   Ins_SRP0( INS_ARG )
  2641.   {
  2642.     DO_SRP0
  2643.   }
  2644.   /*************************************************************************/
  2645.   /*                                                                       */
  2646.   /* SRP1[]:       Set Reference Point 1                                   */
  2647.   /* Opcode range: 0x11                                                    */
  2648.   /* Stack:        uint32 -->                                              */
  2649.   /*                                                                       */
  2650.   static void
  2651.   Ins_SRP1( INS_ARG )
  2652.   {
  2653.     DO_SRP1
  2654.   }
  2655.   /*************************************************************************/
  2656.   /*                                                                       */
  2657.   /* SRP2[]:       Set Reference Point 2                                   */
  2658.   /* Opcode range: 0x12                                                    */
  2659.   /* Stack:        uint32 -->                                              */
  2660.   /*                                                                       */
  2661.   static void
  2662.   Ins_SRP2( INS_ARG )
  2663.   {
  2664.     DO_SRP2
  2665.   }
  2666.   /*************************************************************************/
  2667.   /*                                                                       */
  2668.   /* RTHG[]:       Round To Half Grid                                      */
  2669.   /* Opcode range: 0x19                                                    */
  2670.   /* Stack:        -->                                                     */
  2671.   /*                                                                       */
  2672.   static void
  2673.   Ins_RTHG( INS_ARG )
  2674.   {
  2675.     DO_RTHG
  2676.   }
  2677.   /*************************************************************************/
  2678.   /*                                                                       */
  2679.   /* RTG[]:        Round To Grid                                           */
  2680.   /* Opcode range: 0x18                                                    */
  2681.   /* Stack:        -->                                                     */
  2682.   /*                                                                       */
  2683.   static void
  2684.   Ins_RTG( INS_ARG )
  2685.   {
  2686.     DO_RTG
  2687.   }
  2688.   /*************************************************************************/
  2689.   /* RTDG[]:       Round To Double Grid                                    */
  2690.   /* Opcode range: 0x3D                                                    */
  2691.   /* Stack:        -->                                                     */
  2692.   /*                                                                       */
  2693.   static void
  2694.   Ins_RTDG( INS_ARG )
  2695.   {
  2696.     DO_RTDG
  2697.   }
  2698.   /*************************************************************************/
  2699.   /* RUTG[]:       Round Up To Grid                                        */
  2700.   /* Opcode range: 0x7C                                                    */
  2701.   /* Stack:        -->                                                     */
  2702.   /*                                                                       */
  2703.   static void
  2704.   Ins_RUTG( INS_ARG )
  2705.   {
  2706.     DO_RUTG
  2707.   }
  2708.   /*************************************************************************/
  2709.   /*                                                                       */
  2710.   /* RDTG[]:       Round Down To Grid                                      */
  2711.   /* Opcode range: 0x7D                                                    */
  2712.   /* Stack:        -->                                                     */
  2713.   /*                                                                       */
  2714.   static void
  2715.   Ins_RDTG( INS_ARG )
  2716.   {
  2717.     DO_RDTG
  2718.   }
  2719.   /*************************************************************************/
  2720.   /*                                                                       */
  2721.   /* ROFF[]:       Round OFF                                               */
  2722.   /* Opcode range: 0x7A                                                    */
  2723.   /* Stack:        -->                                                     */
  2724.   /*                                                                       */
  2725.   static void
  2726.   Ins_ROFF( INS_ARG )
  2727.   {
  2728.     DO_ROFF
  2729.   }
  2730.   /*************************************************************************/
  2731.   /*                                                                       */
  2732.   /* SROUND[]:     Super ROUND                                             */
  2733.   /* Opcode range: 0x76                                                    */
  2734.   /* Stack:        Eint8 -->                                               */
  2735.   /*                                                                       */
  2736.   static void
  2737.   Ins_SROUND( INS_ARG )
  2738.   {
  2739.     DO_SROUND
  2740.   }
  2741.   /*************************************************************************/
  2742.   /*                                                                       */
  2743.   /* S45ROUND[]:   Super ROUND 45 degrees                                  */
  2744.   /* Opcode range: 0x77                                                    */
  2745.   /* Stack:        uint32 -->                                              */
  2746.   /*                                                                       */
  2747.   static void
  2748.   Ins_S45ROUND( INS_ARG )
  2749.   {
  2750.     DO_S45ROUND
  2751.   }
  2752.   /*************************************************************************/
  2753.   /*                                                                       */
  2754.   /* SLOOP[]:      Set LOOP variable                                       */
  2755.   /* Opcode range: 0x17                                                    */
  2756.   /* Stack:        int32? -->                                              */
  2757.   /*                                                                       */
  2758.   static void
  2759.   Ins_SLOOP( INS_ARG )
  2760.   {
  2761.     DO_SLOOP
  2762.   }
  2763.   /*************************************************************************/
  2764.   /*                                                                       */
  2765.   /* SMD[]:        Set Minimum Distance                                    */
  2766.   /* Opcode range: 0x1A                                                    */
  2767.   /* Stack:        f26.6 -->                                               */
  2768.   /*                                                                       */
  2769.   static void
  2770.   Ins_SMD( INS_ARG )
  2771.   {
  2772.     DO_SMD
  2773.   }
  2774.   /*************************************************************************/
  2775.   /*                                                                       */
  2776.   /* SCVTCI[]:     Set Control Value Table Cut In                          */
  2777.   /* Opcode range: 0x1D                                                    */
  2778.   /* Stack:        f26.6 -->                                               */
  2779.   /*                                                                       */
  2780.   static void
  2781.   Ins_SCVTCI( INS_ARG )
  2782.   {
  2783.     DO_SCVTCI
  2784.   }
  2785.   /*************************************************************************/
  2786.   /*                                                                       */
  2787.   /* SSWCI[]:      Set Single Width Cut In                                 */
  2788.   /* Opcode range: 0x1E                                                    */
  2789.   /* Stack:        f26.6 -->                                               */
  2790.   /*                                                                       */
  2791.   static void
  2792.   Ins_SSWCI( INS_ARG )
  2793.   {
  2794.     DO_SSWCI
  2795.   }
  2796.   /*************************************************************************/
  2797.   /*                                                                       */
  2798.   /* SSW[]:        Set Single Width                                        */
  2799.   /* Opcode range: 0x1F                                                    */
  2800.   /* Stack:        int32? -->                                              */
  2801.   /*                                                                       */
  2802.   static void
  2803.   Ins_SSW( INS_ARG )
  2804.   {
  2805.     DO_SSW
  2806.   }
  2807.   /*************************************************************************/
  2808.   /*                                                                       */
  2809.   /* FLIPON[]:     Set auto-FLIP to ON                                     */
  2810.   /* Opcode range: 0x4D                                                    */
  2811.   /* Stack:        -->                                                     */
  2812.   /*                                                                       */
  2813.   static void
  2814.   Ins_FLIPON( INS_ARG )
  2815.   {
  2816.     DO_FLIPON
  2817.   }
  2818.   /*************************************************************************/
  2819.   /*                                                                       */
  2820.   /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
  2821.   /* Opcode range: 0x4E                                                    */
  2822.   /* Stack: -->                                                            */
  2823.   /*                                                                       */
  2824.   static void
  2825.   Ins_FLIPOFF( INS_ARG )
  2826.   {
  2827.     DO_FLIPOFF
  2828.   }
  2829.   /*************************************************************************/
  2830.   /*                                                                       */
  2831.   /* SANGW[]:      Set ANGle Weight                                        */
  2832.   /* Opcode range: 0x7E                                                    */
  2833.   /* Stack:        uint32 -->                                              */
  2834.   /*                                                                       */
  2835.   static void
  2836.   Ins_SANGW( INS_ARG )
  2837.   {
  2838.     /* instruction not supported anymore */
  2839.   }
  2840.   /*************************************************************************/
  2841.   /*                                                                       */
  2842.   /* SDB[]:        Set Delta Base                                          */
  2843.   /* Opcode range: 0x5E                                                    */
  2844.   /* Stack:        uint32 -->                                              */
  2845.   /*                                                                       */
  2846.   static void
  2847.   Ins_SDB( INS_ARG )
  2848.   {
  2849.     DO_SDB
  2850.   }
  2851.   /*************************************************************************/
  2852.   /*                                                                       */
  2853.   /* SDS[]:        Set Delta Shift                                         */
  2854.   /* Opcode range: 0x5F                                                    */
  2855.   /* Stack:        uint32 -->                                              */
  2856.   /*                                                                       */
  2857.   static void
  2858.   Ins_SDS( INS_ARG )
  2859.   {
  2860.     DO_SDS
  2861.   }
  2862.   /*************************************************************************/
  2863.   /*                                                                       */
  2864.   /* MPPEM[]:      Measure Pixel Per EM                                    */
  2865.   /* Opcode range: 0x4B                                                    */
  2866.   /* Stack:        --> Euint16                                             */
  2867.   /*                                                                       */
  2868.   static void
  2869.   Ins_MPPEM( INS_ARG )
  2870.   {
  2871.     DO_MPPEM
  2872.   }
  2873.   /*************************************************************************/
  2874.   /*                                                                       */
  2875.   /* MPS[]:        Measure Point Size                                      */
  2876.   /* Opcode range: 0x4C                                                    */
  2877.   /* Stack:        --> Euint16                                             */
  2878.   /*                                                                       */
  2879.   static void
  2880.   Ins_MPS( INS_ARG )
  2881.   {
  2882.     DO_MPS
  2883.   }
  2884.   /*************************************************************************/
  2885.   /*                                                                       */
  2886.   /* DUP[]:        DUPlicate the top stack's element                       */
  2887.   /* Opcode range: 0x20                                                    */
  2888.   /* Stack:        StkElt --> StkElt StkElt                                */
  2889.   /*                                                                       */
  2890.   static void
  2891.   Ins_DUP( INS_ARG )
  2892.   {
  2893.     DO_DUP
  2894.   }
  2895.   /*************************************************************************/
  2896.   /*                                                                       */
  2897.   /* POP[]:        POP the stack's top element                             */
  2898.   /* Opcode range: 0x21                                                    */
  2899.   /* Stack:        StkElt -->                                              */
  2900.   /*                                                                       */
  2901.   static void
  2902.   Ins_POP( INS_ARG )
  2903.   {
  2904.     /* nothing to do */
  2905.   }
  2906.   /*************************************************************************/
  2907.   /*                                                                       */
  2908.   /* CLEAR[]:      CLEAR the entire stack                                  */
  2909.   /* Opcode range: 0x22                                                    */
  2910.   /* Stack:        StkElt... -->                                           */
  2911.   /*                                                                       */
  2912.   static void
  2913.   Ins_CLEAR( INS_ARG )
  2914.   {
  2915.     DO_CLEAR
  2916.   }
  2917.   /*************************************************************************/
  2918.   /*                                                                       */
  2919.   /* SWAP[]:       SWAP the stack's top two elements                       */
  2920.   /* Opcode range: 0x23                                                    */
  2921.   /* Stack:        2 * StkElt --> 2 * StkElt                               */
  2922.   /*                                                                       */
  2923.   static void
  2924.   Ins_SWAP( INS_ARG )
  2925.   {
  2926.     DO_SWAP
  2927.   }
  2928.   /*************************************************************************/
  2929.   /*                                                                       */
  2930.   /* DEPTH[]:      return the stack DEPTH                                  */
  2931.   /* Opcode range: 0x24                                                    */
  2932.   /* Stack:        --> uint32                                              */
  2933.   /*                                                                       */
  2934.   static void
  2935.   Ins_DEPTH( INS_ARG )
  2936.   {
  2937.     DO_DEPTH
  2938.   }
  2939.   /*************************************************************************/
  2940.   /*                                                                       */
  2941.   /* CINDEX[]:     Copy INDEXed element                                    */
  2942.   /* Opcode range: 0x25                                                    */
  2943.   /* Stack:        int32 --> StkElt                                        */
  2944.   /*                                                                       */
  2945.   static void
  2946.   Ins_CINDEX( INS_ARG )
  2947.   {
  2948.     DO_CINDEX
  2949.   }
  2950.   /*************************************************************************/
  2951.   /*                                                                       */
  2952.   /* EIF[]:        End IF                                                  */
  2953.   /* Opcode range: 0x59                                                    */
  2954.   /* Stack:        -->                                                     */
  2955.   /*                                                                       */
  2956.   static void
  2957.   Ins_EIF( INS_ARG )
  2958.   {
  2959.     /* nothing to do */
  2960.   }
  2961.   /*************************************************************************/
  2962.   /*                                                                       */
  2963.   /* JROT[]:       Jump Relative On True                                   */
  2964.   /* Opcode range: 0x78                                                    */
  2965.   /* Stack:        StkElt int32 -->                                        */
  2966.   /*                                                                       */
  2967.   static void
  2968.   Ins_JROT( INS_ARG )
  2969.   {
  2970.     DO_JROT
  2971.   }
  2972.   /*************************************************************************/
  2973.   /*                                                                       */
  2974.   /* JMPR[]:       JuMP Relative                                           */
  2975.   /* Opcode range: 0x1C                                                    */
  2976.   /* Stack:        int32 -->                                               */
  2977.   /*                                                                       */
  2978.   static void
  2979.   Ins_JMPR( INS_ARG )
  2980.   {
  2981.     DO_JMPR
  2982.   }
  2983.   /*************************************************************************/
  2984.   /*                                                                       */
  2985.   /* JROF[]:       Jump Relative On False                                  */
  2986.   /* Opcode range: 0x79                                                    */
  2987.   /* Stack:        StkElt int32 -->                                        */
  2988.   /*                                                                       */
  2989.   static void
  2990.   Ins_JROF( INS_ARG )
  2991.   {
  2992.     DO_JROF
  2993.   }
  2994.   /*************************************************************************/
  2995.   /*                                                                       */
  2996.   /* LT[]:         Less Than                                               */
  2997.   /* Opcode range: 0x50                                                    */
  2998.   /* Stack:        int32? int32? --> bool                                  */
  2999.   /*                                                                       */
  3000.   static void
  3001.   Ins_LT( INS_ARG )
  3002.   {
  3003.     DO_LT
  3004.   }
  3005.   /*************************************************************************/
  3006.   /*                                                                       */
  3007.   /* LTEQ[]:       Less Than or EQual                                      */
  3008.   /* Opcode range: 0x51                                                    */
  3009.   /* Stack:        int32? int32? --> bool                                  */
  3010.   /*                                                                       */
  3011.   static void
  3012.   Ins_LTEQ( INS_ARG )
  3013.   {
  3014.     DO_LTEQ
  3015.   }
  3016.   /*************************************************************************/
  3017.   /*                                                                       */
  3018.   /* GT[]:         Greater Than                                            */
  3019.   /* Opcode range: 0x52                                                    */
  3020.   /* Stack:        int32? int32? --> bool                                  */
  3021.   /*                                                                       */
  3022.   static void
  3023.   Ins_GT( INS_ARG )
  3024.   {
  3025.     DO_GT
  3026.   }
  3027.   /*************************************************************************/
  3028.   /*                                                                       */
  3029.   /* GTEQ[]:       Greater Than or EQual                                   */
  3030.   /* Opcode range: 0x53                                                    */
  3031.   /* Stack:        int32? int32? --> bool                                  */
  3032.   /*                                                                       */
  3033.   static void
  3034.   Ins_GTEQ( INS_ARG )
  3035.   {
  3036.     DO_GTEQ
  3037.   }
  3038.   /*************************************************************************/
  3039.   /*                                                                       */
  3040.   /* EQ[]:         EQual                                                   */
  3041.   /* Opcode range: 0x54                                                    */
  3042.   /* Stack:        StkElt StkElt --> bool                                  */
  3043.   /*                                                                       */
  3044.   static void
  3045.   Ins_EQ( INS_ARG )
  3046.   {
  3047.     DO_EQ
  3048.   }
  3049.   /*************************************************************************/
  3050.   /*                                                                       */
  3051.   /* NEQ[]:        Not EQual                                               */
  3052.   /* Opcode range: 0x55                                                    */
  3053.   /* Stack:        StkElt StkElt --> bool                                  */
  3054.   /*                                                                       */
  3055.   static void
  3056.   Ins_NEQ( INS_ARG )
  3057.   {
  3058.     DO_NEQ
  3059.   }
  3060.   /*************************************************************************/
  3061.   /*                                                                       */
  3062.   /* ODD[]:        Is ODD                                                  */
  3063.   /* Opcode range: 0x56                                                    */
  3064.   /* Stack:        f26.6 --> bool                                          */
  3065.   /*                                                                       */
  3066.   static void
  3067.   Ins_ODD( INS_ARG )
  3068.   {
  3069.     DO_ODD
  3070.   }
  3071.   /*************************************************************************/
  3072.   /*                                                                       */
  3073.   /* EVEN[]:       Is EVEN                                                 */
  3074.   /* Opcode range: 0x57                                                    */
  3075.   /* Stack:        f26.6 --> bool                                          */
  3076.   /*                                                                       */
  3077.   static void
  3078.   Ins_EVEN( INS_ARG )
  3079.   {
  3080.     DO_EVEN
  3081.   }
  3082.   /*************************************************************************/
  3083.   /*                                                                       */
  3084.   /* AND[]:        logical AND                                             */
  3085.   /* Opcode range: 0x5A                                                    */
  3086.   /* Stack:        uint32 uint32 --> uint32                                */
  3087.   /*                                                                       */
  3088.   static void
  3089.   Ins_AND( INS_ARG )
  3090.   {
  3091.     DO_AND
  3092.   }
  3093.   /*************************************************************************/
  3094.   /*                                                                       */
  3095.   /* OR[]:         logical OR                                              */
  3096.   /* Opcode range: 0x5B                                                    */
  3097.   /* Stack:        uint32 uint32 --> uint32                                */
  3098.   /*                                                                       */
  3099.   static void
  3100.   Ins_OR( INS_ARG )
  3101.   {
  3102.     DO_OR
  3103.   }
  3104.   /*************************************************************************/
  3105.   /*                                                                       */
  3106.   /* NOT[]:        logical NOT                                             */
  3107.   /* Opcode range: 0x5C                                                    */
  3108.   /* Stack:        StkElt --> uint32                                       */
  3109.   /*                                                                       */
  3110.   static void
  3111.   Ins_NOT( INS_ARG )
  3112.   {
  3113.     DO_NOT
  3114.   }
  3115.   /*************************************************************************/
  3116.   /*                                                                       */
  3117.   /* ADD[]:        ADD                                                     */
  3118.   /* Opcode range: 0x60                                                    */
  3119.   /* Stack:        f26.6 f26.6 --> f26.6                                   */
  3120.   /*                                                                       */
  3121.   static void
  3122.   Ins_ADD( INS_ARG )
  3123.   {
  3124.     DO_ADD
  3125.   }
  3126.   /*************************************************************************/
  3127.   /*                                                                       */
  3128.   /* SUB[]:        SUBtract                                                */
  3129.   /* Opcode range: 0x61                                                    */
  3130.   /* Stack:        f26.6 f26.6 --> f26.6                                   */
  3131.   /*                                                                       */
  3132.   static void
  3133.   Ins_SUB( INS_ARG )
  3134.   {
  3135.     DO_SUB
  3136.   }
  3137.   /*************************************************************************/
  3138.   /*                                                                       */
  3139.   /* DIV[]:        DIVide                                                  */
  3140.   /* Opcode range: 0x62                                                    */
  3141.   /* Stack:        f26.6 f26.6 --> f26.6                                   */
  3142.   /*                                                                       */
  3143.   static void
  3144.   Ins_DIV( INS_ARG )
  3145.   {
  3146.     DO_DIV
  3147.   }
  3148.   /*************************************************************************/
  3149.   /*                                                                       */
  3150.   /* MUL[]:        MULtiply                                                */
  3151.   /* Opcode range: 0x63                                                    */
  3152.   /* Stack:        f26.6 f26.6 --> f26.6                                   */
  3153.   /*                                                                       */
  3154.   static void
  3155.   Ins_MUL( INS_ARG )
  3156.   {
  3157.     DO_MUL
  3158.   }
  3159.   /*************************************************************************/
  3160.   /*                                                                       */
  3161.   /* ABS[]:        ABSolute value                                          */
  3162.   /* Opcode range: 0x64                                                    */
  3163.   /* Stack:        f26.6 --> f26.6                                         */
  3164.   /*                                                                       */
  3165.   static void
  3166.   Ins_ABS( INS_ARG )
  3167.   {
  3168.     DO_ABS
  3169.   }
  3170.   /*************************************************************************/
  3171.   /*                                                                       */
  3172.   /* NEG[]:        NEGate                                                  */
  3173.   /* Opcode range: 0x65                                                    */
  3174.   /* Stack: f26.6 --> f26.6                                                */
  3175.   /*                                                                       */
  3176.   static void
  3177.   Ins_NEG( INS_ARG )
  3178.   {
  3179.     DO_NEG
  3180.   }
  3181.   /*************************************************************************/
  3182.   /*                                                                       */
  3183.   /* FLOOR[]:      FLOOR                                                   */
  3184.   /* Opcode range: 0x66                                                    */
  3185.   /* Stack:        f26.6 --> f26.6                                         */
  3186.   /*                                                                       */
  3187.   static void
  3188.   Ins_FLOOR( INS_ARG )
  3189.   {
  3190.     DO_FLOOR
  3191.   }