| Index: third_party/freetype/src/truetype/ttinterp.c
|
| diff --git a/third_party/freetype/src/truetype/ttinterp.c b/third_party/freetype/src/truetype/ttinterp.c
|
| index 6bdffbca52762b0515f8ae9bf0adf8089cea965c..ae2a82adc5ede6a1206fbd8482237d9d8cbab309 100644
|
| --- a/third_party/freetype/src/truetype/ttinterp.c
|
| +++ b/third_party/freetype/src/truetype/ttinterp.c
|
| @@ -4,8 +4,8 @@
|
| /* */
|
| /* TrueType bytecode interpreter (body). */
|
| /* */
|
| -/* Copyright 1996-2014 */
|
| -/* by David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| +/* Copyright 1996-2015 by */
|
| +/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| /* modified, and distributed under the terms of the FreeType project */
|
| @@ -44,6 +44,7 @@
|
| #undef FT_COMPONENT
|
| #define FT_COMPONENT trace_ttinterp
|
|
|
| +
|
| /*************************************************************************/
|
| /* */
|
| /* In order to detect infinite loops in the code, we set up a counter */
|
| @@ -53,174 +54,30 @@
|
| #define MAX_RUNNABLE_OPCODES 1000000L
|
|
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* There are two kinds of implementations: */
|
| - /* */
|
| - /* a. static implementation */
|
| - /* */
|
| - /* The current execution context is a static variable, which fields */
|
| - /* are accessed directly by the interpreter during execution. The */
|
| - /* context is named `cur'. */
|
| - /* */
|
| - /* This version is non-reentrant, of course. */
|
| - /* */
|
| - /* b. indirect implementation */
|
| - /* */
|
| - /* The current execution context is passed to _each_ function as its */
|
| - /* first argument, and each field is thus accessed indirectly. */
|
| - /* */
|
| - /* This version is fully re-entrant. */
|
| - /* */
|
| - /* The idea is that an indirect implementation may be slower to execute */
|
| - /* on low-end processors that are used in some systems (like 386s or */
|
| - /* even 486s). */
|
| - /* */
|
| - /* As a consequence, the indirect implementation is now the default, as */
|
| - /* its performance costs can be considered negligible in our context. */
|
| - /* Note, however, that we kept the same source with macros because: */
|
| - /* */
|
| - /* - The code is kept very close in design to the Pascal code used for */
|
| - /* development. */
|
| - /* */
|
| - /* - It's much more readable that way! */
|
| - /* */
|
| - /* - It's still open to experimentation and tuning. */
|
| - /* */
|
| - /*************************************************************************/
|
| -
|
| -
|
| -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
|
| -
|
| -#define CUR (*exc) /* see ttobjs.h */
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* This macro is used whenever `exec' is unused in a function, to avoid */
|
| - /* stupid warnings from pedantic compilers. */
|
| - /* */
|
| -#define FT_UNUSED_EXEC FT_UNUSED( exc )
|
| -
|
| -#else /* static implementation */
|
| -
|
| -#define CUR cur
|
| -
|
| -#define FT_UNUSED_EXEC int __dummy = __dummy
|
| -
|
| - static
|
| - TT_ExecContextRec cur; /* static exec. context variable */
|
| -
|
| - /* apparently, we have a _lot_ of direct indexing when accessing */
|
| - /* the static `cur', which makes the code bigger (due to all the */
|
| - /* four bytes addresses). */
|
| -
|
| -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* The instruction argument stack. */
|
| - /* */
|
| -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* This macro is used whenever `args' is unused in a function, to avoid */
|
| - /* stupid warnings from pedantic compilers. */
|
| - /* */
|
| -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args )
|
| -
|
| -
|
| -#define SUBPIXEL_HINTING \
|
| - ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
|
| +#define SUBPIXEL_HINTING \
|
| + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
|
| TT_INTERPRETER_VERSION_38 )
|
|
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */
|
| - /* increase readability of the code. */
|
| - /* */
|
| - /*************************************************************************/
|
| -
|
| -
|
| -#define SKIP_Code() \
|
| - SkipCode( EXEC_ARG )
|
| -
|
| -#define GET_ShortIns() \
|
| - GetShortIns( EXEC_ARG )
|
| -
|
| -#define NORMalize( x, y, v ) \
|
| - Normalize( EXEC_ARG_ x, y, v )
|
| -
|
| -#define SET_SuperRound( scale, flags ) \
|
| - SetSuperRound( EXEC_ARG_ scale, flags )
|
| -
|
| -#define ROUND_None( d, c ) \
|
| - Round_None( EXEC_ARG_ d, c )
|
| -
|
| -#define INS_Goto_CodeRange( range, ip ) \
|
| - Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
|
| -
|
| -#define CUR_Func_move( z, p, d ) \
|
| - CUR.func_move( EXEC_ARG_ z, p, d )
|
| -
|
| -#define CUR_Func_move_orig( z, p, d ) \
|
| - CUR.func_move_orig( EXEC_ARG_ z, p, d )
|
| -
|
| -#define CUR_Func_round( d, c ) \
|
| - CUR.func_round( EXEC_ARG_ d, c )
|
| -
|
| -#define CUR_Func_cur_ppem() \
|
| - CUR.func_cur_ppem( EXEC_ARG )
|
| -
|
| -#define CUR_Func_read_cvt( index ) \
|
| - CUR.func_read_cvt( EXEC_ARG_ index )
|
| -
|
| -#define CUR_Func_write_cvt( index, val ) \
|
| - CUR.func_write_cvt( EXEC_ARG_ index, val )
|
| -
|
| -#define CUR_Func_move_cvt( index, val ) \
|
| - CUR.func_move_cvt( EXEC_ARG_ index, val )
|
| -
|
| -#define CURRENT_Ratio() \
|
| - Current_Ratio( EXEC_ARG )
|
| -
|
| -#define INS_SxVTL( a, b, c, d ) \
|
| - Ins_SxVTL( EXEC_ARG_ a, b, c, d )
|
| -
|
| -#define COMPUTE_Funcs() \
|
| - Compute_Funcs( EXEC_ARG )
|
| -
|
| -#define COMPUTE_Round( a ) \
|
| - Compute_Round( EXEC_ARG_ a )
|
| +#define PROJECT( v1, v2 ) \
|
| + exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
|
|
|
| -#define COMPUTE_Point_Displacement( a, b, c, d ) \
|
| - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
|
| +#define DUALPROJ( v1, v2 ) \
|
| + exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
|
|
|
| -#define MOVE_Zp2_Point( a, b, c, t ) \
|
| - Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
|
| +#define FAST_PROJECT( v ) \
|
| + exc->func_project( exc, (v)->x, (v)->y )
|
|
|
| -
|
| -#define CUR_Func_project( v1, v2 ) \
|
| - CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
|
| -
|
| -#define CUR_Func_dualproj( v1, v2 ) \
|
| - CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
|
| -
|
| -#define CUR_fast_project( v ) \
|
| - CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
|
| -
|
| -#define CUR_fast_dualproj( v ) \
|
| - CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
|
| +#define FAST_DUALPROJ( v ) \
|
| + exc->func_dualproj( exc, (v)->x, (v)->y )
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| /* Instruction dispatch function, as used by the interpreter. */
|
| /* */
|
| - typedef void (*TInstruction_Function)( INS_ARG );
|
| + typedef void (*TInstruction_Function)( TT_ExecContext exc,
|
| + FT_Long* args );
|
|
|
|
|
| /*************************************************************************/
|
| @@ -230,13 +87,6 @@
|
| #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
|
| #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) )
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* This macro computes (a*2^14)/b and complements TT_MulFix14. */
|
| - /* */
|
| -#define TT_DivFix14( a, b ) \
|
| - FT_DivFix( a, (b) << 2 )
|
| -
|
|
|
| #undef SUCCESS
|
| #define SUCCESS 0
|
| @@ -245,16 +95,20 @@
|
| #define FAILURE 1
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| -#define GUESS_VECTOR( V ) \
|
| - if ( CUR.face->unpatented_hinting ) \
|
| - { \
|
| - CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
|
| - CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
|
| - }
|
| +#define GUESS_VECTOR( V ) \
|
| + do \
|
| + { \
|
| + if ( exc->face->unpatented_hinting ) \
|
| + { \
|
| + exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
|
| + exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
|
| + } \
|
| + } while (0)
|
| #else
|
| -#define GUESS_VECTOR( V )
|
| +#define GUESS_VECTOR( V ) do { } while (0)
|
| #endif
|
|
|
| +
|
| /*************************************************************************/
|
| /* */
|
| /* CODERANGE FUNCTIONS */
|
| @@ -297,7 +151,7 @@
|
| /* which will return to the first byte *after* the code */
|
| /* range, we test for IP <= Size instead of IP < Size. */
|
| /* */
|
| - FT_ASSERT( (FT_ULong)IP <= coderange->size );
|
| + FT_ASSERT( IP <= coderange->size );
|
|
|
| exec->code = coderange->base;
|
| exec->codeSize = coderange->size;
|
| @@ -498,7 +352,7 @@
|
| FT_LOCAL_DEF( FT_Error )
|
| Update_Max( FT_Memory memory,
|
| FT_ULong* size,
|
| - FT_Long multiplier,
|
| + FT_ULong multiplier,
|
| void* _pbuff,
|
| FT_ULong new_max )
|
| {
|
| @@ -591,13 +445,13 @@
|
|
|
| /* XXX: We reserve a little more elements on the stack to deal safely */
|
| /* with broken fonts like arialbs, courbs, timesbs, etc. */
|
| - tmp = exec->stackSize;
|
| + tmp = (FT_ULong)exec->stackSize;
|
| error = Update_Max( exec->memory,
|
| &tmp,
|
| sizeof ( FT_F26Dot6 ),
|
| (void*)&exec->stack,
|
| maxp->maxStackElements + 32 );
|
| - exec->stackSize = (FT_UInt)tmp;
|
| + exec->stackSize = (FT_Long)tmp;
|
| if ( error )
|
| return error;
|
|
|
| @@ -683,12 +537,8 @@
|
| /* <Return> */
|
| /* TrueType error code. 0 means success. */
|
| /* */
|
| - /* <Note> */
|
| - /* Only the glyph loader and debugger should call this function. */
|
| - /* */
|
| FT_LOCAL_DEF( FT_Error )
|
| - TT_Run_Context( TT_ExecContext exec,
|
| - FT_Bool debug )
|
| + TT_Run_Context( TT_ExecContext exec )
|
| {
|
| TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
|
|
|
| @@ -718,16 +568,7 @@
|
| exec->top = 0;
|
| exec->callTop = 0;
|
|
|
| -#if 1
|
| - FT_UNUSED( debug );
|
| -
|
| return exec->face->interpreter( exec );
|
| -#else
|
| - if ( !debug )
|
| - return TT_RunIns( exec );
|
| - else
|
| - return FT_Err_Ok;
|
| -#endif
|
| }
|
|
|
|
|
| @@ -761,6 +602,9 @@
|
| TT_New_Context( TT_Driver driver )
|
| {
|
| FT_Memory memory;
|
| + FT_Error error;
|
| +
|
| + TT_ExecContext exec = NULL;
|
|
|
|
|
| if ( !driver )
|
| @@ -768,26 +612,16 @@
|
|
|
| memory = driver->root.root.memory;
|
|
|
| - if ( !driver->context )
|
| - {
|
| - FT_Error error;
|
| - TT_ExecContext exec;
|
| -
|
| -
|
| - /* allocate object */
|
| - if ( FT_NEW( exec ) )
|
| - goto Fail;
|
| -
|
| - /* initialize it; in case of error this deallocates `exec' too */
|
| - error = Init_Context( exec, memory );
|
| - if ( error )
|
| - goto Fail;
|
| + /* allocate object */
|
| + if ( FT_NEW( exec ) )
|
| + goto Fail;
|
|
|
| - /* store it into the driver */
|
| - driver->context = exec;
|
| - }
|
| + /* initialize it; in case of error this deallocates `exec' too */
|
| + error = Init_Context( exec, memory );
|
| + if ( error )
|
| + goto Fail;
|
|
|
| - return driver->context;
|
| + return exec;
|
|
|
| Fail:
|
| return NULL;
|
| @@ -834,8 +668,8 @@
|
| /* SFvTL + */ PACK( 2, 0 ),
|
| /* SPvFS */ PACK( 2, 0 ),
|
| /* SFvFS */ PACK( 2, 0 ),
|
| - /* GPV */ PACK( 0, 2 ),
|
| - /* GFV */ PACK( 0, 2 ),
|
| + /* GPv */ PACK( 0, 2 ),
|
| + /* GFv */ PACK( 0, 2 ),
|
| /* SFvTPv */ PACK( 0, 0 ),
|
| /* ISECT */ PACK( 5, 0 ),
|
|
|
| @@ -964,8 +798,8 @@
|
| /* INS_$83 */ PACK( 0, 0 ),
|
| /* INS_$84 */ PACK( 0, 0 ),
|
| /* ScanCTRL */ PACK( 1, 0 ),
|
| - /* SDPVTL[0] */ PACK( 2, 0 ),
|
| - /* SDPVTL[1] */ PACK( 2, 0 ),
|
| + /* SDPvTL[0] */ PACK( 2, 0 ),
|
| + /* SDPvTL[1] */ PACK( 2, 0 ),
|
| /* GetINFO */ PACK( 1, 1 ),
|
| /* IDEF */ PACK( 1, 0 ),
|
| /* ROLL */ PACK( 3, 3 ),
|
| @@ -1098,280 +932,284 @@
|
|
|
| #ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
| + /* the first hex digit gives the length of the opcode name; the space */
|
| + /* after the digit is here just to increase readability of the source */
|
| + /* code */
|
| +
|
| static
|
| const char* const opcode_name[256] =
|
| {
|
| - "SVTCA y",
|
| - "SVTCA x",
|
| - "SPvTCA y",
|
| - "SPvTCA x",
|
| - "SFvTCA y",
|
| - "SFvTCA x",
|
| - "SPvTL ||",
|
| - "SPvTL +",
|
| - "SFvTL ||",
|
| - "SFvTL +",
|
| - "SPvFS",
|
| - "SFvFS",
|
| - "GPV",
|
| - "GFV",
|
| - "SFvTPv",
|
| - "ISECT",
|
| -
|
| - "SRP0",
|
| - "SRP1",
|
| - "SRP2",
|
| - "SZP0",
|
| - "SZP1",
|
| - "SZP2",
|
| - "SZPS",
|
| - "SLOOP",
|
| - "RTG",
|
| - "RTHG",
|
| - "SMD",
|
| - "ELSE",
|
| - "JMPR",
|
| - "SCvTCi",
|
| - "SSwCi",
|
| - "SSW",
|
| -
|
| - "DUP",
|
| - "POP",
|
| - "CLEAR",
|
| - "SWAP",
|
| - "DEPTH",
|
| - "CINDEX",
|
| - "MINDEX",
|
| - "AlignPTS",
|
| - "INS_$28",
|
| - "UTP",
|
| - "LOOPCALL",
|
| - "CALL",
|
| - "FDEF",
|
| - "ENDF",
|
| - "MDAP[0]",
|
| - "MDAP[1]",
|
| -
|
| - "IUP[0]",
|
| - "IUP[1]",
|
| - "SHP[0]",
|
| - "SHP[1]",
|
| - "SHC[0]",
|
| - "SHC[1]",
|
| - "SHZ[0]",
|
| - "SHZ[1]",
|
| - "SHPIX",
|
| - "IP",
|
| - "MSIRP[0]",
|
| - "MSIRP[1]",
|
| - "AlignRP",
|
| - "RTDG",
|
| - "MIAP[0]",
|
| - "MIAP[1]",
|
| -
|
| - "NPushB",
|
| - "NPushW",
|
| - "WS",
|
| - "RS",
|
| - "WCvtP",
|
| - "RCvt",
|
| - "GC[0]",
|
| - "GC[1]",
|
| - "SCFS",
|
| - "MD[0]",
|
| - "MD[1]",
|
| - "MPPEM",
|
| - "MPS",
|
| - "FlipON",
|
| - "FlipOFF",
|
| - "DEBUG",
|
| -
|
| - "LT",
|
| - "LTEQ",
|
| - "GT",
|
| - "GTEQ",
|
| - "EQ",
|
| - "NEQ",
|
| - "ODD",
|
| - "EVEN",
|
| - "IF",
|
| - "EIF",
|
| - "AND",
|
| - "OR",
|
| - "NOT",
|
| - "DeltaP1",
|
| - "SDB",
|
| - "SDS",
|
| -
|
| - "ADD",
|
| - "SUB",
|
| - "DIV",
|
| - "MUL",
|
| - "ABS",
|
| - "NEG",
|
| - "FLOOR",
|
| - "CEILING",
|
| - "ROUND[0]",
|
| - "ROUND[1]",
|
| - "ROUND[2]",
|
| - "ROUND[3]",
|
| - "NROUND[0]",
|
| - "NROUND[1]",
|
| - "NROUND[2]",
|
| - "NROUND[3]",
|
| -
|
| - "WCvtF",
|
| - "DeltaP2",
|
| - "DeltaP3",
|
| - "DeltaCn[0]",
|
| - "DeltaCn[1]",
|
| - "DeltaCn[2]",
|
| - "SROUND",
|
| - "S45Round",
|
| - "JROT",
|
| - "JROF",
|
| - "ROFF",
|
| - "INS_$7B",
|
| - "RUTG",
|
| - "RDTG",
|
| - "SANGW",
|
| - "AA",
|
| -
|
| - "FlipPT",
|
| - "FlipRgON",
|
| - "FlipRgOFF",
|
| - "INS_$83",
|
| - "INS_$84",
|
| - "ScanCTRL",
|
| - "SDVPTL[0]",
|
| - "SDVPTL[1]",
|
| - "GetINFO",
|
| - "IDEF",
|
| - "ROLL",
|
| - "MAX",
|
| - "MIN",
|
| - "ScanTYPE",
|
| - "InstCTRL",
|
| - "INS_$8F",
|
| -
|
| - "INS_$90",
|
| - "INS_$91",
|
| - "INS_$92",
|
| - "INS_$93",
|
| - "INS_$94",
|
| - "INS_$95",
|
| - "INS_$96",
|
| - "INS_$97",
|
| - "INS_$98",
|
| - "INS_$99",
|
| - "INS_$9A",
|
| - "INS_$9B",
|
| - "INS_$9C",
|
| - "INS_$9D",
|
| - "INS_$9E",
|
| - "INS_$9F",
|
| -
|
| - "INS_$A0",
|
| - "INS_$A1",
|
| - "INS_$A2",
|
| - "INS_$A3",
|
| - "INS_$A4",
|
| - "INS_$A5",
|
| - "INS_$A6",
|
| - "INS_$A7",
|
| - "INS_$A8",
|
| - "INS_$A9",
|
| - "INS_$AA",
|
| - "INS_$AB",
|
| - "INS_$AC",
|
| - "INS_$AD",
|
| - "INS_$AE",
|
| - "INS_$AF",
|
| -
|
| - "PushB[0]",
|
| - "PushB[1]",
|
| - "PushB[2]",
|
| - "PushB[3]",
|
| - "PushB[4]",
|
| - "PushB[5]",
|
| - "PushB[6]",
|
| - "PushB[7]",
|
| - "PushW[0]",
|
| - "PushW[1]",
|
| - "PushW[2]",
|
| - "PushW[3]",
|
| - "PushW[4]",
|
| - "PushW[5]",
|
| - "PushW[6]",
|
| - "PushW[7]",
|
| -
|
| - "MDRP[00]",
|
| - "MDRP[01]",
|
| - "MDRP[02]",
|
| - "MDRP[03]",
|
| - "MDRP[04]",
|
| - "MDRP[05]",
|
| - "MDRP[06]",
|
| - "MDRP[07]",
|
| - "MDRP[08]",
|
| - "MDRP[09]",
|
| - "MDRP[10]",
|
| - "MDRP[11]",
|
| - "MDRP[12]",
|
| - "MDRP[13]",
|
| - "MDRP[14]",
|
| - "MDRP[15]",
|
| -
|
| - "MDRP[16]",
|
| - "MDRP[17]",
|
| - "MDRP[18]",
|
| - "MDRP[19]",
|
| - "MDRP[20]",
|
| - "MDRP[21]",
|
| - "MDRP[22]",
|
| - "MDRP[23]",
|
| - "MDRP[24]",
|
| - "MDRP[25]",
|
| - "MDRP[26]",
|
| - "MDRP[27]",
|
| - "MDRP[28]",
|
| - "MDRP[29]",
|
| - "MDRP[30]",
|
| - "MDRP[31]",
|
| -
|
| - "MIRP[00]",
|
| - "MIRP[01]",
|
| - "MIRP[02]",
|
| - "MIRP[03]",
|
| - "MIRP[04]",
|
| - "MIRP[05]",
|
| - "MIRP[06]",
|
| - "MIRP[07]",
|
| - "MIRP[08]",
|
| - "MIRP[09]",
|
| - "MIRP[10]",
|
| - "MIRP[11]",
|
| - "MIRP[12]",
|
| - "MIRP[13]",
|
| - "MIRP[14]",
|
| - "MIRP[15]",
|
| -
|
| - "MIRP[16]",
|
| - "MIRP[17]",
|
| - "MIRP[18]",
|
| - "MIRP[19]",
|
| - "MIRP[20]",
|
| - "MIRP[21]",
|
| - "MIRP[22]",
|
| - "MIRP[23]",
|
| - "MIRP[24]",
|
| - "MIRP[25]",
|
| - "MIRP[26]",
|
| - "MIRP[27]",
|
| - "MIRP[28]",
|
| - "MIRP[29]",
|
| - "MIRP[30]",
|
| - "MIRP[31]"
|
| + "7 SVTCA y",
|
| + "7 SVTCA x",
|
| + "8 SPvTCA y",
|
| + "8 SPvTCA x",
|
| + "8 SFvTCA y",
|
| + "8 SFvTCA x",
|
| + "8 SPvTL ||",
|
| + "7 SPvTL +",
|
| + "8 SFvTL ||",
|
| + "7 SFvTL +",
|
| + "5 SPvFS",
|
| + "5 SFvFS",
|
| + "3 GPv",
|
| + "3 GFv",
|
| + "6 SFvTPv",
|
| + "5 ISECT",
|
| +
|
| + "4 SRP0",
|
| + "4 SRP1",
|
| + "4 SRP2",
|
| + "4 SZP0",
|
| + "4 SZP1",
|
| + "4 SZP2",
|
| + "4 SZPS",
|
| + "5 SLOOP",
|
| + "3 RTG",
|
| + "4 RTHG",
|
| + "3 SMD",
|
| + "4 ELSE",
|
| + "4 JMPR",
|
| + "6 SCvTCi",
|
| + "5 SSwCi",
|
| + "3 SSW",
|
| +
|
| + "3 DUP",
|
| + "3 POP",
|
| + "5 CLEAR",
|
| + "4 SWAP",
|
| + "5 DEPTH",
|
| + "6 CINDEX",
|
| + "6 MINDEX",
|
| + "8 AlignPTS",
|
| + "7 INS_$28",
|
| + "3 UTP",
|
| + "8 LOOPCALL",
|
| + "4 CALL",
|
| + "4 FDEF",
|
| + "4 ENDF",
|
| + "7 MDAP[0]",
|
| + "7 MDAP[1]",
|
| +
|
| + "6 IUP[0]",
|
| + "6 IUP[1]",
|
| + "6 SHP[0]",
|
| + "6 SHP[1]",
|
| + "6 SHC[0]",
|
| + "6 SHC[1]",
|
| + "6 SHZ[0]",
|
| + "6 SHZ[1]",
|
| + "5 SHPIX",
|
| + "2 IP",
|
| + "8 MSIRP[0]",
|
| + "8 MSIRP[1]",
|
| + "7 AlignRP",
|
| + "4 RTDG",
|
| + "7 MIAP[0]",
|
| + "7 MIAP[1]",
|
| +
|
| + "6 NPushB",
|
| + "6 NPushW",
|
| + "2 WS",
|
| + "2 RS",
|
| + "5 WCvtP",
|
| + "4 RCvt",
|
| + "5 GC[0]",
|
| + "5 GC[1]",
|
| + "4 SCFS",
|
| + "5 MD[0]",
|
| + "5 MD[1]",
|
| + "5 MPPEM",
|
| + "3 MPS",
|
| + "6 FlipON",
|
| + "7 FlipOFF",
|
| + "5 DEBUG",
|
| +
|
| + "2 LT",
|
| + "4 LTEQ",
|
| + "2 GT",
|
| + "4 GTEQ",
|
| + "2 EQ",
|
| + "3 NEQ",
|
| + "3 ODD",
|
| + "4 EVEN",
|
| + "2 IF",
|
| + "3 EIF",
|
| + "3 AND",
|
| + "2 OR",
|
| + "3 NOT",
|
| + "7 DeltaP1",
|
| + "3 SDB",
|
| + "3 SDS",
|
| +
|
| + "3 ADD",
|
| + "3 SUB",
|
| + "3 DIV",
|
| + "3 MUL",
|
| + "3 ABS",
|
| + "3 NEG",
|
| + "5 FLOOR",
|
| + "7 CEILING",
|
| + "8 ROUND[0]",
|
| + "8 ROUND[1]",
|
| + "8 ROUND[2]",
|
| + "8 ROUND[3]",
|
| + "9 NROUND[0]",
|
| + "9 NROUND[1]",
|
| + "9 NROUND[2]",
|
| + "9 NROUND[3]",
|
| +
|
| + "5 WCvtF",
|
| + "7 DeltaP2",
|
| + "7 DeltaP3",
|
| + "A DeltaCn[0]",
|
| + "A DeltaCn[1]",
|
| + "A DeltaCn[2]",
|
| + "6 SROUND",
|
| + "8 S45Round",
|
| + "4 JROT",
|
| + "4 JROF",
|
| + "4 ROFF",
|
| + "7 INS_$7B",
|
| + "4 RUTG",
|
| + "4 RDTG",
|
| + "5 SANGW",
|
| + "2 AA",
|
| +
|
| + "6 FlipPT",
|
| + "8 FlipRgON",
|
| + "9 FlipRgOFF",
|
| + "7 INS_$83",
|
| + "7 INS_$84",
|
| + "8 ScanCTRL",
|
| + "9 SDPvTL[0]",
|
| + "9 SDPvTL[1]",
|
| + "7 GetINFO",
|
| + "4 IDEF",
|
| + "4 ROLL",
|
| + "3 MAX",
|
| + "3 MIN",
|
| + "8 ScanTYPE",
|
| + "8 InstCTRL",
|
| + "7 INS_$8F",
|
| +
|
| + "7 INS_$90",
|
| + "7 INS_$91",
|
| + "7 INS_$92",
|
| + "7 INS_$93",
|
| + "7 INS_$94",
|
| + "7 INS_$95",
|
| + "7 INS_$96",
|
| + "7 INS_$97",
|
| + "7 INS_$98",
|
| + "7 INS_$99",
|
| + "7 INS_$9A",
|
| + "7 INS_$9B",
|
| + "7 INS_$9C",
|
| + "7 INS_$9D",
|
| + "7 INS_$9E",
|
| + "7 INS_$9F",
|
| +
|
| + "7 INS_$A0",
|
| + "7 INS_$A1",
|
| + "7 INS_$A2",
|
| + "7 INS_$A3",
|
| + "7 INS_$A4",
|
| + "7 INS_$A5",
|
| + "7 INS_$A6",
|
| + "7 INS_$A7",
|
| + "7 INS_$A8",
|
| + "7 INS_$A9",
|
| + "7 INS_$AA",
|
| + "7 INS_$AB",
|
| + "7 INS_$AC",
|
| + "7 INS_$AD",
|
| + "7 INS_$AE",
|
| + "7 INS_$AF",
|
| +
|
| + "8 PushB[0]",
|
| + "8 PushB[1]",
|
| + "8 PushB[2]",
|
| + "8 PushB[3]",
|
| + "8 PushB[4]",
|
| + "8 PushB[5]",
|
| + "8 PushB[6]",
|
| + "8 PushB[7]",
|
| + "8 PushW[0]",
|
| + "8 PushW[1]",
|
| + "8 PushW[2]",
|
| + "8 PushW[3]",
|
| + "8 PushW[4]",
|
| + "8 PushW[5]",
|
| + "8 PushW[6]",
|
| + "8 PushW[7]",
|
| +
|
| + "8 MDRP[00]",
|
| + "8 MDRP[01]",
|
| + "8 MDRP[02]",
|
| + "8 MDRP[03]",
|
| + "8 MDRP[04]",
|
| + "8 MDRP[05]",
|
| + "8 MDRP[06]",
|
| + "8 MDRP[07]",
|
| + "8 MDRP[08]",
|
| + "8 MDRP[09]",
|
| + "8 MDRP[10]",
|
| + "8 MDRP[11]",
|
| + "8 MDRP[12]",
|
| + "8 MDRP[13]",
|
| + "8 MDRP[14]",
|
| + "8 MDRP[15]",
|
| +
|
| + "8 MDRP[16]",
|
| + "8 MDRP[17]",
|
| + "8 MDRP[18]",
|
| + "8 MDRP[19]",
|
| + "8 MDRP[20]",
|
| + "8 MDRP[21]",
|
| + "8 MDRP[22]",
|
| + "8 MDRP[23]",
|
| + "8 MDRP[24]",
|
| + "8 MDRP[25]",
|
| + "8 MDRP[26]",
|
| + "8 MDRP[27]",
|
| + "8 MDRP[28]",
|
| + "8 MDRP[29]",
|
| + "8 MDRP[30]",
|
| + "8 MDRP[31]",
|
| +
|
| + "8 MIRP[00]",
|
| + "8 MIRP[01]",
|
| + "8 MIRP[02]",
|
| + "8 MIRP[03]",
|
| + "8 MIRP[04]",
|
| + "8 MIRP[05]",
|
| + "8 MIRP[06]",
|
| + "8 MIRP[07]",
|
| + "8 MIRP[08]",
|
| + "8 MIRP[09]",
|
| + "8 MIRP[10]",
|
| + "8 MIRP[11]",
|
| + "8 MIRP[12]",
|
| + "8 MIRP[13]",
|
| + "8 MIRP[14]",
|
| + "8 MIRP[15]",
|
| +
|
| + "8 MIRP[16]",
|
| + "8 MIRP[17]",
|
| + "8 MIRP[18]",
|
| + "8 MIRP[19]",
|
| + "8 MIRP[20]",
|
| + "8 MIRP[21]",
|
| + "8 MIRP[22]",
|
| + "8 MIRP[23]",
|
| + "8 MIRP[24]",
|
| + "8 MIRP[25]",
|
| + "8 MIRP[26]",
|
| + "8 MIRP[27]",
|
| + "8 MIRP[28]",
|
| + "8 MIRP[29]",
|
| + "8 MIRP[30]",
|
| + "8 MIRP[31]"
|
| };
|
|
|
| #endif /* FT_DEBUG_LEVEL_TRACE */
|
| @@ -1637,55 +1475,55 @@
|
| /* The aspect ratio in 16.16 format, always <= 1.0 . */
|
| /* */
|
| static FT_Long
|
| - Current_Ratio( EXEC_OP )
|
| + Current_Ratio( TT_ExecContext exc )
|
| {
|
| - if ( !CUR.tt_metrics.ratio )
|
| + if ( !exc->tt_metrics.ratio )
|
| {
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - if ( CUR.GS.both_x_axis )
|
| - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
|
| + if ( exc->GS.both_x_axis )
|
| + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
|
| else
|
| - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
|
| + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
|
| }
|
| else
|
| #endif
|
| {
|
| - if ( CUR.GS.projVector.y == 0 )
|
| - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
|
| + if ( exc->GS.projVector.y == 0 )
|
| + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
|
|
|
| - else if ( CUR.GS.projVector.x == 0 )
|
| - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
|
| + else if ( exc->GS.projVector.x == 0 )
|
| + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
|
|
|
| else
|
| {
|
| FT_F26Dot6 x, y;
|
|
|
|
|
| - x = TT_MulFix14( CUR.tt_metrics.x_ratio,
|
| - CUR.GS.projVector.x );
|
| - y = TT_MulFix14( CUR.tt_metrics.y_ratio,
|
| - CUR.GS.projVector.y );
|
| - CUR.tt_metrics.ratio = FT_Hypot( x, y );
|
| + x = TT_MulFix14( exc->tt_metrics.x_ratio,
|
| + exc->GS.projVector.x );
|
| + y = TT_MulFix14( exc->tt_metrics.y_ratio,
|
| + exc->GS.projVector.y );
|
| + exc->tt_metrics.ratio = FT_Hypot( x, y );
|
| }
|
| }
|
| }
|
| - return CUR.tt_metrics.ratio;
|
| + return exc->tt_metrics.ratio;
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( FT_Long )
|
| - Current_Ppem( EXEC_OP )
|
| + Current_Ppem( TT_ExecContext exc )
|
| {
|
| - return CUR.tt_metrics.ppem;
|
| + return exc->tt_metrics.ppem;
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( FT_Long )
|
| - Current_Ppem_Stretched( EXEC_OP )
|
| + Current_Ppem_Stretched( TT_ExecContext exc )
|
| {
|
| - return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
|
| + return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
|
| }
|
|
|
|
|
| @@ -1697,48 +1535,54 @@
|
|
|
|
|
| FT_CALLBACK_DEF( FT_F26Dot6 )
|
| - Read_CVT( EXEC_OP_ FT_ULong idx )
|
| + Read_CVT( TT_ExecContext exc,
|
| + FT_ULong idx )
|
| {
|
| - return CUR.cvt[idx];
|
| + return exc->cvt[idx];
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( FT_F26Dot6 )
|
| - Read_CVT_Stretched( EXEC_OP_ FT_ULong idx )
|
| + Read_CVT_Stretched( TT_ExecContext exc,
|
| + FT_ULong idx )
|
| {
|
| - return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
|
| + return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( void )
|
| - Write_CVT( EXEC_OP_ FT_ULong idx,
|
| - FT_F26Dot6 value )
|
| + Write_CVT( TT_ExecContext exc,
|
| + FT_ULong idx,
|
| + FT_F26Dot6 value )
|
| {
|
| - CUR.cvt[idx] = value;
|
| + exc->cvt[idx] = value;
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( void )
|
| - Write_CVT_Stretched( EXEC_OP_ FT_ULong idx,
|
| - FT_F26Dot6 value )
|
| + Write_CVT_Stretched( TT_ExecContext exc,
|
| + FT_ULong idx,
|
| + FT_F26Dot6 value )
|
| {
|
| - CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
|
| + exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( void )
|
| - Move_CVT( EXEC_OP_ FT_ULong idx,
|
| - FT_F26Dot6 value )
|
| + Move_CVT( TT_ExecContext exc,
|
| + FT_ULong idx,
|
| + FT_F26Dot6 value )
|
| {
|
| - CUR.cvt[idx] += value;
|
| + exc->cvt[idx] += value;
|
| }
|
|
|
|
|
| FT_CALLBACK_DEF( void )
|
| - Move_CVT_Stretched( EXEC_OP_ FT_ULong idx,
|
| - FT_F26Dot6 value )
|
| + Move_CVT_Stretched( TT_ExecContext exc,
|
| + FT_ULong idx,
|
| + FT_F26Dot6 value )
|
| {
|
| - CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
|
| + exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
|
| }
|
|
|
|
|
| @@ -1758,12 +1602,12 @@
|
| /* This one could become a macro. */
|
| /* */
|
| static FT_Short
|
| - GetShortIns( EXEC_OP )
|
| + GetShortIns( TT_ExecContext exc )
|
| {
|
| /* Reading a byte stream so there is no endianess (DaveP) */
|
| - CUR.IP += 2;
|
| - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
|
| - CUR.code[CUR.IP - 1] );
|
| + exc->IP += 2;
|
| + return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
|
| + exc->code[exc->IP - 1] );
|
| }
|
|
|
|
|
| @@ -1784,23 +1628,24 @@
|
| /* SUCCESS or FAILURE. */
|
| /* */
|
| static FT_Bool
|
| - Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange,
|
| - FT_ULong aIP )
|
| + Ins_Goto_CodeRange( TT_ExecContext exc,
|
| + FT_Int aRange,
|
| + FT_Long aIP )
|
| {
|
| TT_CodeRange* range;
|
|
|
|
|
| if ( aRange < 1 || aRange > 3 )
|
| {
|
| - CUR.error = FT_THROW( Bad_Argument );
|
| + exc->error = FT_THROW( Bad_Argument );
|
| return FAILURE;
|
| }
|
|
|
| - range = &CUR.codeRangeTable[aRange - 1];
|
| + range = &exc->codeRangeTable[aRange - 1];
|
|
|
| if ( range->base == NULL ) /* invalid coderange */
|
| {
|
| - CUR.error = FT_THROW( Invalid_CodeRange );
|
| + exc->error = FT_THROW( Invalid_CodeRange );
|
| return FAILURE;
|
| }
|
|
|
| @@ -1810,14 +1655,14 @@
|
|
|
| if ( aIP > range->size )
|
| {
|
| - CUR.error = FT_THROW( Code_Overflow );
|
| + exc->error = FT_THROW( Code_Overflow );
|
| return FAILURE;
|
| }
|
|
|
| - CUR.code = range->base;
|
| - CUR.codeSize = range->size;
|
| - CUR.IP = aIP;
|
| - CUR.curRange = aRange;
|
| + exc->code = range->base;
|
| + exc->codeSize = range->size;
|
| + exc->IP = aIP;
|
| + exc->curRange = aRange;
|
|
|
| return SUCCESS;
|
| }
|
| @@ -1841,36 +1686,37 @@
|
| /* zone :: The affected glyph zone. */
|
| /* */
|
| static void
|
| - Direct_Move( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| FT_F26Dot6 v;
|
|
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - FT_ASSERT( !CUR.face->unpatented_hinting );
|
| + FT_ASSERT( !exc->face->unpatented_hinting );
|
| #endif
|
|
|
| - v = CUR.GS.freeVector.x;
|
| + v = exc->GS.freeVector.x;
|
|
|
| if ( v != 0 )
|
| {
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( !SUBPIXEL_HINTING ||
|
| - ( !CUR.ignore_x_mode ||
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
|
| + if ( !SUBPIXEL_HINTING ||
|
| + ( !exc->ignore_x_mode ||
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| - zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
|
| + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
|
|
|
| zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
| }
|
|
|
| - v = CUR.GS.freeVector.y;
|
| + v = exc->GS.freeVector.y;
|
|
|
| if ( v != 0 )
|
| {
|
| - zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
|
| + zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
|
|
|
| zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| }
|
| @@ -1895,26 +1741,27 @@
|
| /* zone :: The affected glyph zone. */
|
| /* */
|
| static void
|
| - Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move_Orig( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| FT_F26Dot6 v;
|
|
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - FT_ASSERT( !CUR.face->unpatented_hinting );
|
| + FT_ASSERT( !exc->face->unpatented_hinting );
|
| #endif
|
|
|
| - v = CUR.GS.freeVector.x;
|
| + v = exc->GS.freeVector.x;
|
|
|
| if ( v != 0 )
|
| - zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
|
| + zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
|
|
|
| - v = CUR.GS.freeVector.y;
|
| + v = exc->GS.freeVector.y;
|
|
|
| if ( v != 0 )
|
| - zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
|
| + zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
|
| }
|
|
|
|
|
| @@ -1929,15 +1776,16 @@
|
|
|
|
|
| static void
|
| - Direct_Move_X( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move_X( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( !SUBPIXEL_HINTING ||
|
| - !CUR.ignore_x_mode )
|
| + if ( !SUBPIXEL_HINTING ||
|
| + !exc->ignore_x_mode )
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| zone->cur[point].x += distance;
|
|
|
| @@ -1946,11 +1794,12 @@
|
|
|
|
|
| static void
|
| - Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move_Y( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
| zone->cur[point].y += distance;
|
| zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| @@ -1968,22 +1817,24 @@
|
|
|
|
|
| static void
|
| - Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move_Orig_X( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
| zone->org[point].x += distance;
|
| }
|
|
|
|
|
| static void
|
| - Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone,
|
| - FT_UShort point,
|
| - FT_F26Dot6 distance )
|
| + Direct_Move_Orig_Y( TT_ExecContext exc,
|
| + TT_GlyphZone zone,
|
| + FT_UShort point,
|
| + FT_F26Dot6 distance )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
| zone->org[point].y += distance;
|
| }
|
| @@ -2012,12 +1863,13 @@
|
| /* before rounding. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_None( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_None( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2053,12 +1905,13 @@
|
| /* Rounded distance. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_To_Grid( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2074,7 +1927,7 @@
|
| val = 0;
|
| }
|
|
|
| - return val;
|
| + return val;
|
| }
|
|
|
|
|
| @@ -2095,12 +1948,13 @@
|
| /* Rounded distance. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_To_Half_Grid( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2137,12 +1991,13 @@
|
| /* Rounded distance. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_Down_To_Grid( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2179,12 +2034,13 @@
|
| /* Rounded distance. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_Up_To_Grid( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2221,12 +2077,13 @@
|
| /* Rounded distance. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_To_Double_Grid( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
|
|
|
|
| if ( distance >= 0 )
|
| @@ -2269,27 +2126,28 @@
|
| /* before rounding. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_Super( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_Super( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = ( distance - CUR.phase + CUR.threshold + compensation ) &
|
| - -CUR.period;
|
| - val += CUR.phase;
|
| + val = ( distance - exc->phase + exc->threshold + compensation ) &
|
| + -exc->period;
|
| + val += exc->phase;
|
| if ( val < 0 )
|
| - val = CUR.phase;
|
| + val = exc->phase;
|
| }
|
| else
|
| {
|
| - val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
|
| - -CUR.period );
|
| - val -= CUR.phase;
|
| + val = -( ( exc->threshold - exc->phase - distance + compensation ) &
|
| + -exc->period );
|
| + val -= exc->phase;
|
| if ( val > 0 )
|
| - val = -CUR.phase;
|
| + val = -exc->phase;
|
| }
|
|
|
| return val;
|
| @@ -2317,27 +2175,28 @@
|
| /* greater precision. */
|
| /* */
|
| static FT_F26Dot6
|
| - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance,
|
| - FT_F26Dot6 compensation )
|
| + Round_Super_45( TT_ExecContext exc,
|
| + FT_F26Dot6 distance,
|
| + FT_F26Dot6 compensation )
|
| {
|
| FT_F26Dot6 val;
|
|
|
|
|
| if ( distance >= 0 )
|
| {
|
| - val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
|
| - CUR.period ) * CUR.period;
|
| - val += CUR.phase;
|
| + val = ( ( distance - exc->phase + exc->threshold + compensation ) /
|
| + exc->period ) * exc->period;
|
| + val += exc->phase;
|
| if ( val < 0 )
|
| - val = CUR.phase;
|
| + val = exc->phase;
|
| }
|
| else
|
| {
|
| - val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
|
| - CUR.period ) * CUR.period );
|
| - val -= CUR.phase;
|
| + val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
|
| + exc->period ) * exc->period );
|
| + val -= exc->phase;
|
| if ( val > 0 )
|
| - val = -CUR.phase;
|
| + val = -exc->phase;
|
| }
|
|
|
| return val;
|
| @@ -2356,40 +2215,41 @@
|
| /* round_mode :: The rounding mode to be used. */
|
| /* */
|
| static void
|
| - Compute_Round( EXEC_OP_ FT_Byte round_mode )
|
| + Compute_Round( TT_ExecContext exc,
|
| + FT_Byte round_mode )
|
| {
|
| switch ( round_mode )
|
| {
|
| case TT_Round_Off:
|
| - CUR.func_round = (TT_Round_Func)Round_None;
|
| + exc->func_round = (TT_Round_Func)Round_None;
|
| break;
|
|
|
| case TT_Round_To_Grid:
|
| - CUR.func_round = (TT_Round_Func)Round_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Grid;
|
| break;
|
|
|
| case TT_Round_Up_To_Grid:
|
| - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
|
| break;
|
|
|
| case TT_Round_Down_To_Grid:
|
| - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
|
| break;
|
|
|
| case TT_Round_To_Half_Grid:
|
| - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
|
| break;
|
|
|
| case TT_Round_To_Double_Grid:
|
| - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
|
| break;
|
|
|
| case TT_Round_Super:
|
| - CUR.func_round = (TT_Round_Func)Round_Super;
|
| + exc->func_round = (TT_Round_Func)Round_Super;
|
| break;
|
|
|
| case TT_Round_Super_45:
|
| - CUR.func_round = (TT_Round_Func)Round_Super_45;
|
| + exc->func_round = (TT_Round_Func)Round_Super_45;
|
| break;
|
| }
|
| }
|
| @@ -2409,57 +2269,58 @@
|
| /* selector :: The SROUND opcode. */
|
| /* */
|
| static void
|
| - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod,
|
| - FT_Long selector )
|
| + SetSuperRound( TT_ExecContext exc,
|
| + FT_F2Dot14 GridPeriod,
|
| + FT_Long selector )
|
| {
|
| switch ( (FT_Int)( selector & 0xC0 ) )
|
| {
|
| case 0:
|
| - CUR.period = GridPeriod / 2;
|
| + exc->period = GridPeriod / 2;
|
| break;
|
|
|
| case 0x40:
|
| - CUR.period = GridPeriod;
|
| + exc->period = GridPeriod;
|
| break;
|
|
|
| case 0x80:
|
| - CUR.period = GridPeriod * 2;
|
| + exc->period = GridPeriod * 2;
|
| break;
|
|
|
| /* This opcode is reserved, but... */
|
| -
|
| case 0xC0:
|
| - CUR.period = GridPeriod;
|
| + exc->period = GridPeriod;
|
| break;
|
| }
|
|
|
| switch ( (FT_Int)( selector & 0x30 ) )
|
| {
|
| case 0:
|
| - CUR.phase = 0;
|
| + exc->phase = 0;
|
| break;
|
|
|
| case 0x10:
|
| - CUR.phase = CUR.period / 4;
|
| + exc->phase = exc->period / 4;
|
| break;
|
|
|
| case 0x20:
|
| - CUR.phase = CUR.period / 2;
|
| + exc->phase = exc->period / 2;
|
| break;
|
|
|
| case 0x30:
|
| - CUR.phase = CUR.period * 3 / 4;
|
| + exc->phase = exc->period * 3 / 4;
|
| break;
|
| }
|
|
|
| if ( ( selector & 0x0F ) == 0 )
|
| - CUR.threshold = CUR.period - 1;
|
| + exc->threshold = exc->period - 1;
|
| else
|
| - CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
|
| + exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
|
|
|
| - CUR.period /= 256;
|
| - CUR.phase /= 256;
|
| - CUR.threshold /= 256;
|
| + /* convert to F26Dot6 format */
|
| + exc->period >>= 8;
|
| + exc->phase >>= 8;
|
| + exc->threshold >>= 8;
|
| }
|
|
|
|
|
| @@ -2480,16 +2341,17 @@
|
| /* The distance in F26dot6 format. */
|
| /* */
|
| static FT_F26Dot6
|
| - Project( EXEC_OP_ FT_Pos dx,
|
| - FT_Pos dy )
|
| + Project( TT_ExecContext exc,
|
| + FT_Pos dx,
|
| + FT_Pos dy )
|
| {
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - FT_ASSERT( !CUR.face->unpatented_hinting );
|
| + FT_ASSERT( !exc->face->unpatented_hinting );
|
| #endif
|
|
|
| - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
|
| - CUR.GS.projVector.x,
|
| - CUR.GS.projVector.y );
|
| + return TT_DotFix14( dx, dy,
|
| + exc->GS.projVector.x,
|
| + exc->GS.projVector.y );
|
| }
|
|
|
|
|
| @@ -2510,12 +2372,13 @@
|
| /* The distance in F26dot6 format. */
|
| /* */
|
| static FT_F26Dot6
|
| - Dual_Project( EXEC_OP_ FT_Pos dx,
|
| - FT_Pos dy )
|
| + Dual_Project( TT_ExecContext exc,
|
| + FT_Pos dx,
|
| + FT_Pos dy )
|
| {
|
| - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
|
| - CUR.GS.dualVector.x,
|
| - CUR.GS.dualVector.y );
|
| + return TT_DotFix14( dx, dy,
|
| + exc->GS.dualVector.x,
|
| + exc->GS.dualVector.y );
|
| }
|
|
|
|
|
| @@ -2536,10 +2399,11 @@
|
| /* The distance in F26dot6 format. */
|
| /* */
|
| static FT_F26Dot6
|
| - Project_x( EXEC_OP_ FT_Pos dx,
|
| - FT_Pos dy )
|
| + Project_x( TT_ExecContext exc,
|
| + FT_Pos dx,
|
| + FT_Pos dy )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
| FT_UNUSED( dy );
|
|
|
| return dx;
|
| @@ -2563,10 +2427,11 @@
|
| /* The distance in F26dot6 format. */
|
| /* */
|
| static FT_F26Dot6
|
| - Project_y( EXEC_OP_ FT_Pos dx,
|
| - FT_Pos dy )
|
| + Project_y( TT_ExecContext exc,
|
| + FT_Pos dx,
|
| + FT_Pos dy )
|
| {
|
| - FT_UNUSED_EXEC;
|
| + FT_UNUSED( exc );
|
| FT_UNUSED( dx );
|
|
|
| return dy;
|
| @@ -2583,101 +2448,101 @@
|
| /* to the current graphics state. */
|
| /* */
|
| static void
|
| - Compute_Funcs( EXEC_OP )
|
| + Compute_Funcs( TT_ExecContext exc )
|
| {
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - /* If both vectors point rightwards along the x axis, set */
|
| - /* `both-x-axis' true, otherwise set it false. The x values only */
|
| - /* need be tested because the vector has been normalised to a unit */
|
| - /* vector of length 0x4000 = unity. */
|
| - CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
|
| - CUR.GS.freeVector.x == 0x4000 );
|
| + /* If both vectors point rightwards along the x axis, set */
|
| + /* `both-x-axis' true, otherwise set it false. The x values only */
|
| + /* need be tested because the vector has been normalised to a unit */
|
| + /* vector of length 0x4000 = unity. */
|
| + exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
|
| + exc->GS.freeVector.x == 0x4000 );
|
|
|
| /* Throw away projection and freedom vector information */
|
| /* because the patents don't allow them to be stored. */
|
| /* The relevant US Patents are 5155805 and 5325479. */
|
| - CUR.GS.projVector.x = 0;
|
| - CUR.GS.projVector.y = 0;
|
| - CUR.GS.freeVector.x = 0;
|
| - CUR.GS.freeVector.y = 0;
|
| + exc->GS.projVector.x = 0;
|
| + exc->GS.projVector.y = 0;
|
| + exc->GS.freeVector.x = 0;
|
| + exc->GS.freeVector.y = 0;
|
|
|
| - if ( CUR.GS.both_x_axis )
|
| + if ( exc->GS.both_x_axis )
|
| {
|
| - CUR.func_project = Project_x;
|
| - CUR.func_move = Direct_Move_X;
|
| - CUR.func_move_orig = Direct_Move_Orig_X;
|
| + exc->func_project = Project_x;
|
| + exc->func_move = Direct_Move_X;
|
| + exc->func_move_orig = Direct_Move_Orig_X;
|
| }
|
| else
|
| {
|
| - CUR.func_project = Project_y;
|
| - CUR.func_move = Direct_Move_Y;
|
| - CUR.func_move_orig = Direct_Move_Orig_Y;
|
| + exc->func_project = Project_y;
|
| + exc->func_move = Direct_Move_Y;
|
| + exc->func_move_orig = Direct_Move_Orig_Y;
|
| }
|
|
|
| - if ( CUR.GS.dualVector.x == 0x4000 )
|
| - CUR.func_dualproj = Project_x;
|
| - else if ( CUR.GS.dualVector.y == 0x4000 )
|
| - CUR.func_dualproj = Project_y;
|
| + if ( exc->GS.dualVector.x == 0x4000 )
|
| + exc->func_dualproj = Project_x;
|
| + else if ( exc->GS.dualVector.y == 0x4000 )
|
| + exc->func_dualproj = Project_y;
|
| else
|
| - CUR.func_dualproj = Dual_Project;
|
| + exc->func_dualproj = Dual_Project;
|
|
|
| /* Force recalculation of cached aspect ratio */
|
| - CUR.tt_metrics.ratio = 0;
|
| + exc->tt_metrics.ratio = 0;
|
|
|
| return;
|
| }
|
| #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
|
|
|
| - if ( CUR.GS.freeVector.x == 0x4000 )
|
| - CUR.F_dot_P = CUR.GS.projVector.x;
|
| - else if ( CUR.GS.freeVector.y == 0x4000 )
|
| - CUR.F_dot_P = CUR.GS.projVector.y;
|
| + if ( exc->GS.freeVector.x == 0x4000 )
|
| + exc->F_dot_P = exc->GS.projVector.x;
|
| + else if ( exc->GS.freeVector.y == 0x4000 )
|
| + exc->F_dot_P = exc->GS.projVector.y;
|
| else
|
| - CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
|
| - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
|
| - 14;
|
| -
|
| - if ( CUR.GS.projVector.x == 0x4000 )
|
| - CUR.func_project = (TT_Project_Func)Project_x;
|
| - else if ( CUR.GS.projVector.y == 0x4000 )
|
| - CUR.func_project = (TT_Project_Func)Project_y;
|
| + exc->F_dot_P =
|
| + ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
|
| + (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
|
| +
|
| + if ( exc->GS.projVector.x == 0x4000 )
|
| + exc->func_project = (TT_Project_Func)Project_x;
|
| + else if ( exc->GS.projVector.y == 0x4000 )
|
| + exc->func_project = (TT_Project_Func)Project_y;
|
| else
|
| - CUR.func_project = (TT_Project_Func)Project;
|
| + exc->func_project = (TT_Project_Func)Project;
|
|
|
| - if ( CUR.GS.dualVector.x == 0x4000 )
|
| - CUR.func_dualproj = (TT_Project_Func)Project_x;
|
| - else if ( CUR.GS.dualVector.y == 0x4000 )
|
| - CUR.func_dualproj = (TT_Project_Func)Project_y;
|
| + if ( exc->GS.dualVector.x == 0x4000 )
|
| + exc->func_dualproj = (TT_Project_Func)Project_x;
|
| + else if ( exc->GS.dualVector.y == 0x4000 )
|
| + exc->func_dualproj = (TT_Project_Func)Project_y;
|
| else
|
| - CUR.func_dualproj = (TT_Project_Func)Dual_Project;
|
| + exc->func_dualproj = (TT_Project_Func)Dual_Project;
|
|
|
| - CUR.func_move = (TT_Move_Func)Direct_Move;
|
| - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
|
| + exc->func_move = (TT_Move_Func)Direct_Move;
|
| + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
|
|
|
| - if ( CUR.F_dot_P == 0x4000L )
|
| + if ( exc->F_dot_P == 0x4000L )
|
| {
|
| - if ( CUR.GS.freeVector.x == 0x4000 )
|
| + if ( exc->GS.freeVector.x == 0x4000 )
|
| {
|
| - CUR.func_move = (TT_Move_Func)Direct_Move_X;
|
| - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
|
| + exc->func_move = (TT_Move_Func)Direct_Move_X;
|
| + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
|
| }
|
| - else if ( CUR.GS.freeVector.y == 0x4000 )
|
| + else if ( exc->GS.freeVector.y == 0x4000 )
|
| {
|
| - CUR.func_move = (TT_Move_Func)Direct_Move_Y;
|
| - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
|
| + exc->func_move = (TT_Move_Func)Direct_Move_Y;
|
| + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
|
| }
|
| }
|
|
|
| /* at small sizes, F_dot_P can become too small, resulting */
|
| /* in overflows and `spikes' in a number of glyphs like `w'. */
|
|
|
| - if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
|
| - CUR.F_dot_P = 0x4000L;
|
| + if ( FT_ABS( exc->F_dot_P ) < 0x400L )
|
| + exc->F_dot_P = 0x4000L;
|
|
|
| /* Disable cached aspect ratio */
|
| - CUR.tt_metrics.ratio = 0;
|
| + exc->tt_metrics.ratio = 0;
|
| }
|
|
|
|
|
| @@ -2700,36 +2565,31 @@
|
| /* Returns FAILURE if a vector parameter is zero. */
|
| /* */
|
| /* <Note> */
|
| - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */
|
| + /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */
|
| /* R is undefined. */
|
| /* */
|
| static FT_Bool
|
| - Normalize( EXEC_OP_ FT_F26Dot6 Vx,
|
| - FT_F26Dot6 Vy,
|
| - FT_UnitVector* R )
|
| + Normalize( FT_F26Dot6 Vx,
|
| + FT_F26Dot6 Vy,
|
| + FT_UnitVector* R )
|
| {
|
| - FT_F26Dot6 W;
|
| -
|
| - FT_UNUSED_EXEC;
|
| + FT_Vector V;
|
|
|
|
|
| - if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L )
|
| + if ( Vx == 0 && Vy == 0 )
|
| {
|
| - if ( Vx == 0 && Vy == 0 )
|
| - {
|
| - /* XXX: UNDOCUMENTED! It seems that it is possible to try */
|
| - /* to normalize the vector (0,0). Return immediately. */
|
| - return SUCCESS;
|
| - }
|
| -
|
| - Vx *= 0x4000;
|
| - Vy *= 0x4000;
|
| + /* XXX: UNDOCUMENTED! It seems that it is possible to try */
|
| + /* to normalize the vector (0,0). Return immediately. */
|
| + return SUCCESS;
|
| }
|
|
|
| - W = FT_Hypot( Vx, Vy );
|
| + V.x = Vx;
|
| + V.y = Vy;
|
|
|
| - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
|
| - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
|
| + FT_Vector_NormLen( &V );
|
| +
|
| + R->x = (FT_F2Dot14)( V.x / 4 );
|
| + R->y = (FT_F2Dot14)( V.y / 4 );
|
|
|
| return SUCCESS;
|
| }
|
| @@ -2742,2521 +2602,2168 @@
|
| /*************************************************************************/
|
|
|
|
|
| - static FT_Bool
|
| - Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1,
|
| - FT_UShort aIdx2,
|
| - FT_Int aOpc,
|
| - FT_UnitVector* Vec )
|
| - {
|
| - FT_Long A, B, C;
|
| - FT_Vector* p1;
|
| - FT_Vector* p2;
|
| -
|
| +#define ARRAY_BOUND_ERROR \
|
| + do \
|
| + { \
|
| + exc->error = FT_THROW( Invalid_Reference ); \
|
| + return; \
|
| + } while (0)
|
|
|
| - if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
|
| - BOUNDS( aIdx2, CUR.zp1.n_points ) )
|
| - {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| - return FAILURE;
|
| - }
|
|
|
| - p1 = CUR.zp1.cur + aIdx2;
|
| - p2 = CUR.zp2.cur + aIdx1;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* MPPEM[]: Measure Pixel Per EM */
|
| + /* Opcode range: 0x4B */
|
| + /* Stack: --> Euint16 */
|
| + /* */
|
| + static void
|
| + Ins_MPPEM( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + args[0] = exc->func_cur_ppem( exc );
|
| + }
|
|
|
| - A = p1->x - p2->x;
|
| - B = p1->y - p2->y;
|
|
|
| - /* If p1 == p2, SPVTL and SFVTL behave the same as */
|
| - /* SPVTCA[X] and SFVTCA[X], respectively. */
|
| - /* */
|
| - /* Confirmed by Greg Hitchcock. */
|
| + /*************************************************************************/
|
| + /* */
|
| + /* MPS[]: Measure Point Size */
|
| + /* Opcode range: 0x4C */
|
| + /* Stack: --> Euint16 */
|
| + /* */
|
| + static void
|
| + Ins_MPS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + /* Note: The point size should be irrelevant in a given font program; */
|
| + /* we thus decide to return only the PPEM value. */
|
| +#if 0
|
| + args[0] = exc->metrics.pointSize;
|
| +#else
|
| + args[0] = exc->func_cur_ppem( exc );
|
| +#endif
|
| + }
|
|
|
| - if ( A == 0 && B == 0 )
|
| - {
|
| - A = 0x4000;
|
| - aOpc = 0;
|
| - }
|
|
|
| - if ( ( aOpc & 1 ) != 0 )
|
| - {
|
| - C = B; /* counter clockwise rotation */
|
| - B = A;
|
| - A = -C;
|
| - }
|
| + /*************************************************************************/
|
| + /* */
|
| + /* DUP[]: DUPlicate the stack's top element */
|
| + /* Opcode range: 0x20 */
|
| + /* Stack: StkElt --> StkElt StkElt */
|
| + /* */
|
| + static void
|
| + Ins_DUP( FT_Long* args )
|
| + {
|
| + args[1] = args[0];
|
| + }
|
|
|
| - NORMalize( A, B, Vec );
|
|
|
| - return SUCCESS;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* POP[]: POP the stack's top element */
|
| + /* Opcode range: 0x21 */
|
| + /* Stack: StkElt --> */
|
| + /* */
|
| + static void
|
| + Ins_POP( void )
|
| + {
|
| + /* nothing to do */
|
| }
|
|
|
|
|
| - /* When not using the big switch statements, the interpreter uses a */
|
| - /* call table defined later below in this source. Each opcode must */
|
| - /* thus have a corresponding function, even trivial ones. */
|
| - /* */
|
| - /* They are all defined there. */
|
| -
|
| -#define DO_SVTCA \
|
| - { \
|
| - FT_Short A, B; \
|
| - \
|
| - \
|
| - A = (FT_Short)( CUR.opcode & 1 ) << 14; \
|
| - B = A ^ (FT_Short)0x4000; \
|
| - \
|
| - CUR.GS.freeVector.x = A; \
|
| - CUR.GS.projVector.x = A; \
|
| - CUR.GS.dualVector.x = A; \
|
| - \
|
| - CUR.GS.freeVector.y = B; \
|
| - CUR.GS.projVector.y = B; \
|
| - CUR.GS.dualVector.y = B; \
|
| - \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SPVTCA \
|
| - { \
|
| - FT_Short A, B; \
|
| - \
|
| - \
|
| - A = (FT_Short)( CUR.opcode & 1 ) << 14; \
|
| - B = A ^ (FT_Short)0x4000; \
|
| - \
|
| - CUR.GS.projVector.x = A; \
|
| - CUR.GS.dualVector.x = A; \
|
| - \
|
| - CUR.GS.projVector.y = B; \
|
| - CUR.GS.dualVector.y = B; \
|
| - \
|
| - GUESS_VECTOR( freeVector ); \
|
| - \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SFVTCA \
|
| - { \
|
| - FT_Short A, B; \
|
| - \
|
| - \
|
| - A = (FT_Short)( CUR.opcode & 1 ) << 14; \
|
| - B = A ^ (FT_Short)0x4000; \
|
| - \
|
| - CUR.GS.freeVector.x = A; \
|
| - CUR.GS.freeVector.y = B; \
|
| - \
|
| - GUESS_VECTOR( projVector ); \
|
| - \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SPVTL \
|
| - if ( INS_SxVTL( (FT_UShort)args[1], \
|
| - (FT_UShort)args[0], \
|
| - CUR.opcode, \
|
| - &CUR.GS.projVector ) == SUCCESS ) \
|
| - { \
|
| - CUR.GS.dualVector = CUR.GS.projVector; \
|
| - GUESS_VECTOR( freeVector ); \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SFVTL \
|
| - if ( INS_SxVTL( (FT_UShort)args[1], \
|
| - (FT_UShort)args[0], \
|
| - CUR.opcode, \
|
| - &CUR.GS.freeVector ) == SUCCESS ) \
|
| - { \
|
| - GUESS_VECTOR( projVector ); \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SFVTPV \
|
| - GUESS_VECTOR( projVector ); \
|
| - CUR.GS.freeVector = CUR.GS.projVector; \
|
| - COMPUTE_Funcs();
|
| -
|
| -
|
| -#define DO_SPVFS \
|
| - { \
|
| - FT_Short S; \
|
| - FT_Long X, Y; \
|
| - \
|
| - \
|
| - /* Only use low 16bits, then sign extend */ \
|
| - S = (FT_Short)args[1]; \
|
| - Y = (FT_Long)S; \
|
| - S = (FT_Short)args[0]; \
|
| - X = (FT_Long)S; \
|
| - \
|
| - NORMalize( X, Y, &CUR.GS.projVector ); \
|
| - \
|
| - CUR.GS.dualVector = CUR.GS.projVector; \
|
| - GUESS_VECTOR( freeVector ); \
|
| - COMPUTE_Funcs(); \
|
| - }
|
| -
|
| -
|
| -#define DO_SFVFS \
|
| - { \
|
| - FT_Short S; \
|
| - FT_Long X, Y; \
|
| - \
|
| - \
|
| - /* Only use low 16bits, then sign extend */ \
|
| - S = (FT_Short)args[1]; \
|
| - Y = (FT_Long)S; \
|
| - S = (FT_Short)args[0]; \
|
| - X = S; \
|
| - \
|
| - NORMalize( X, Y, &CUR.GS.freeVector ); \
|
| - GUESS_VECTOR( projVector ); \
|
| - COMPUTE_Funcs(); \
|
| + /*************************************************************************/
|
| + /* */
|
| + /* CLEAR[]: CLEAR the entire stack */
|
| + /* Opcode range: 0x22 */
|
| + /* Stack: StkElt... --> */
|
| + /* */
|
| + static void
|
| + Ins_CLEAR( TT_ExecContext exc )
|
| + {
|
| + exc->new_top = 0;
|
| }
|
|
|
|
|
| -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| -#define DO_GPV \
|
| - if ( CUR.face->unpatented_hinting ) \
|
| - { \
|
| - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
|
| - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
|
| - } \
|
| - else \
|
| - { \
|
| - args[0] = CUR.GS.projVector.x; \
|
| - args[1] = CUR.GS.projVector.y; \
|
| - }
|
| -#else
|
| -#define DO_GPV \
|
| - args[0] = CUR.GS.projVector.x; \
|
| - args[1] = CUR.GS.projVector.y;
|
| -#endif
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SWAP[]: SWAP the stack's top two elements */
|
| + /* Opcode range: 0x23 */
|
| + /* Stack: 2 * StkElt --> 2 * StkElt */
|
| + /* */
|
| + static void
|
| + Ins_SWAP( FT_Long* args )
|
| + {
|
| + FT_Long L;
|
|
|
|
|
| -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| -#define DO_GFV \
|
| - if ( CUR.face->unpatented_hinting ) \
|
| - { \
|
| - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
|
| - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
|
| - } \
|
| - else \
|
| - { \
|
| - args[0] = CUR.GS.freeVector.x; \
|
| - args[1] = CUR.GS.freeVector.y; \
|
| - }
|
| -#else
|
| -#define DO_GFV \
|
| - args[0] = CUR.GS.freeVector.x; \
|
| - args[1] = CUR.GS.freeVector.y;
|
| -#endif
|
| + L = args[0];
|
| + args[0] = args[1];
|
| + args[1] = L;
|
| + }
|
|
|
|
|
| -#define DO_SRP0 \
|
| - CUR.GS.rp0 = (FT_UShort)args[0];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* DEPTH[]: return the stack DEPTH */
|
| + /* Opcode range: 0x24 */
|
| + /* Stack: --> uint32 */
|
| + /* */
|
| + static void
|
| + Ins_DEPTH( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + args[0] = exc->top;
|
| + }
|
|
|
|
|
| -#define DO_SRP1 \
|
| - CUR.GS.rp1 = (FT_UShort)args[0];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* LT[]: Less Than */
|
| + /* Opcode range: 0x50 */
|
| + /* Stack: int32? int32? --> bool */
|
| + /* */
|
| + static void
|
| + Ins_LT( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] < args[1] );
|
| + }
|
|
|
|
|
| -#define DO_SRP2 \
|
| - CUR.GS.rp2 = (FT_UShort)args[0];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* LTEQ[]: Less Than or EQual */
|
| + /* Opcode range: 0x51 */
|
| + /* Stack: int32? int32? --> bool */
|
| + /* */
|
| + static void
|
| + Ins_LTEQ( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] <= args[1] );
|
| + }
|
|
|
|
|
| -#define DO_RTHG \
|
| - CUR.GS.round_state = TT_Round_To_Half_Grid; \
|
| - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* GT[]: Greater Than */
|
| + /* Opcode range: 0x52 */
|
| + /* Stack: int32? int32? --> bool */
|
| + /* */
|
| + static void
|
| + Ins_GT( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] > args[1] );
|
| + }
|
|
|
|
|
| -#define DO_RTG \
|
| - CUR.GS.round_state = TT_Round_To_Grid; \
|
| - CUR.func_round = (TT_Round_Func)Round_To_Grid;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* GTEQ[]: Greater Than or EQual */
|
| + /* Opcode range: 0x53 */
|
| + /* Stack: int32? int32? --> bool */
|
| + /* */
|
| + static void
|
| + Ins_GTEQ( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] >= args[1] );
|
| + }
|
|
|
|
|
| -#define DO_RTDG \
|
| - CUR.GS.round_state = TT_Round_To_Double_Grid; \
|
| - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* EQ[]: EQual */
|
| + /* Opcode range: 0x54 */
|
| + /* Stack: StkElt StkElt --> bool */
|
| + /* */
|
| + static void
|
| + Ins_EQ( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] == args[1] );
|
| + }
|
|
|
|
|
| -#define DO_RUTG \
|
| - CUR.GS.round_state = TT_Round_Up_To_Grid; \
|
| - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
|
| -
|
| -
|
| -#define DO_RDTG \
|
| - CUR.GS.round_state = TT_Round_Down_To_Grid; \
|
| - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
|
| -
|
| -
|
| -#define DO_ROFF \
|
| - CUR.GS.round_state = TT_Round_Off; \
|
| - CUR.func_round = (TT_Round_Func)Round_None;
|
| -
|
| -
|
| -#define DO_SROUND \
|
| - SET_SuperRound( 0x4000, args[0] ); \
|
| - CUR.GS.round_state = TT_Round_Super; \
|
| - CUR.func_round = (TT_Round_Func)Round_Super;
|
| -
|
| -
|
| -#define DO_S45ROUND \
|
| - SET_SuperRound( 0x2D41, args[0] ); \
|
| - CUR.GS.round_state = TT_Round_Super_45; \
|
| - CUR.func_round = (TT_Round_Func)Round_Super_45;
|
| -
|
| -
|
| -#define DO_SLOOP \
|
| - if ( args[0] < 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - else \
|
| - CUR.GS.loop = args[0];
|
| -
|
| -
|
| -#define DO_SMD \
|
| - CUR.GS.minimum_distance = args[0];
|
| -
|
| -
|
| -#define DO_SCVTCI \
|
| - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
|
| -
|
| -
|
| -#define DO_SSWCI \
|
| - CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
|
| -
|
| -
|
| -#define DO_SSW \
|
| - CUR.GS.single_width_value = FT_MulFix( args[0], \
|
| - CUR.tt_metrics.scale );
|
| -
|
| -
|
| -#define DO_FLIPON \
|
| - CUR.GS.auto_flip = TRUE;
|
| -
|
| -
|
| -#define DO_FLIPOFF \
|
| - CUR.GS.auto_flip = FALSE;
|
| -
|
| -
|
| -#define DO_SDB \
|
| - CUR.GS.delta_base = (FT_UShort)args[0];
|
| -
|
| -
|
| -#define DO_SDS \
|
| - if ( (FT_ULong)args[0] > 6UL ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - else \
|
| - CUR.GS.delta_shift = (FT_UShort)args[0];
|
| -
|
| -
|
| -#define DO_MD /* nothing */
|
| -
|
| -
|
| -#define DO_MPPEM \
|
| - args[0] = CUR_Func_cur_ppem();
|
| -
|
| -
|
| - /* Note: The pointSize should be irrelevant in a given font program; */
|
| - /* we thus decide to return only the ppem. */
|
| -#if 0
|
| -
|
| -#define DO_MPS \
|
| - args[0] = CUR.metrics.pointSize;
|
| -
|
| -#else
|
| -
|
| -#define DO_MPS \
|
| - args[0] = CUR_Func_cur_ppem();
|
| -
|
| -#endif /* 0 */
|
| -
|
| -
|
| -#define DO_DUP \
|
| - args[1] = args[0];
|
| -
|
| -
|
| -#define DO_CLEAR \
|
| - CUR.new_top = 0;
|
| -
|
| -
|
| -#define DO_SWAP \
|
| - { \
|
| - FT_Long L; \
|
| - \
|
| - \
|
| - L = args[0]; \
|
| - args[0] = args[1]; \
|
| - args[1] = L; \
|
| - }
|
| -
|
| -
|
| -#define DO_DEPTH \
|
| - args[0] = CUR.top;
|
| -
|
| -
|
| -#define DO_CINDEX \
|
| - { \
|
| - FT_Long L; \
|
| - \
|
| - \
|
| - L = args[0]; \
|
| - \
|
| - if ( L <= 0 || L > CUR.args ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - CUR.error = FT_THROW( Invalid_Reference ); \
|
| - args[0] = 0; \
|
| - } \
|
| - else \
|
| - args[0] = CUR.stack[CUR.args - L]; \
|
| - }
|
| -
|
| -
|
| -#define DO_JROT \
|
| - if ( args[1] != 0 ) \
|
| - { \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.step_ins = FALSE; \
|
| - }
|
| -
|
| -
|
| -#define DO_JMPR \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.step_ins = FALSE;
|
| -
|
| -
|
| -#define DO_JROF \
|
| - if ( args[1] == 0 ) \
|
| - { \
|
| - if ( args[0] == 0 && CUR.args == 0 ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.IP += args[0]; \
|
| - if ( CUR.IP < 0 || \
|
| - ( CUR.callTop > 0 && \
|
| - CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
|
| - CUR.error = FT_THROW( Bad_Argument ); \
|
| - CUR.step_ins = FALSE; \
|
| - }
|
| -
|
| -
|
| -#define DO_LT \
|
| - args[0] = ( args[0] < args[1] );
|
| -
|
| -
|
| -#define DO_LTEQ \
|
| - args[0] = ( args[0] <= args[1] );
|
| -
|
| -
|
| -#define DO_GT \
|
| - args[0] = ( args[0] > args[1] );
|
| -
|
| -
|
| -#define DO_GTEQ \
|
| - args[0] = ( args[0] >= args[1] );
|
| -
|
| -
|
| -#define DO_EQ \
|
| - args[0] = ( args[0] == args[1] );
|
| -
|
| -
|
| -#define DO_NEQ \
|
| - args[0] = ( args[0] != args[1] );
|
| -
|
| -
|
| -#define DO_ODD \
|
| - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
|
| -
|
| -
|
| -#define DO_EVEN \
|
| - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
|
| -
|
| -
|
| -#define DO_AND \
|
| - args[0] = ( args[0] && args[1] );
|
| -
|
| -
|
| -#define DO_OR \
|
| - args[0] = ( args[0] || args[1] );
|
| -
|
| -
|
| -#define DO_NOT \
|
| - args[0] = !args[0];
|
| -
|
| -
|
| -#define DO_ADD \
|
| - args[0] += args[1];
|
| -
|
| -
|
| -#define DO_SUB \
|
| - args[0] -= args[1];
|
| -
|
| -
|
| -#define DO_DIV \
|
| - if ( args[1] == 0 ) \
|
| - CUR.error = FT_THROW( Divide_By_Zero ); \
|
| - else \
|
| - args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
|
| -
|
| -
|
| -#define DO_MUL \
|
| - args[0] = FT_MulDiv( args[0], args[1], 64L );
|
| -
|
| -
|
| -#define DO_ABS \
|
| - args[0] = FT_ABS( args[0] );
|
| -
|
| -
|
| -#define DO_NEG \
|
| - args[0] = -args[0];
|
| -
|
| -
|
| -#define DO_FLOOR \
|
| - args[0] = FT_PIX_FLOOR( args[0] );
|
| -
|
| -
|
| -#define DO_CEILING \
|
| - args[0] = FT_PIX_CEIL( args[0] );
|
| -
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| -
|
| -#define DO_RS \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.storeSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - ARRAY_BOUND_ERROR; \
|
| - else \
|
| - args[0] = 0; \
|
| - } \
|
| - else \
|
| - { \
|
| - /* subpixel hinting - avoid Typeman Dstroke and */ \
|
| - /* IStroke and Vacuform rounds */ \
|
| - \
|
| - if ( SUBPIXEL_HINTING && \
|
| - CUR.ignore_x_mode && \
|
| - ( ( I == 24 && \
|
| - ( CUR.face->sph_found_func_flags & \
|
| - ( SPH_FDEF_SPACING_1 | \
|
| - SPH_FDEF_SPACING_2 ) ) ) || \
|
| - ( I == 22 && \
|
| - ( CUR.sph_in_func_flags & \
|
| - SPH_FDEF_TYPEMAN_STROKES ) ) || \
|
| - ( I == 8 && \
|
| - ( CUR.face->sph_found_func_flags & \
|
| - SPH_FDEF_VACUFORM_ROUND_1 ) && \
|
| - CUR.iup_called ) ) ) \
|
| - args[0] = 0; \
|
| - else \
|
| - args[0] = CUR.storage[I]; \
|
| - } \
|
| - }
|
| -
|
| -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| -
|
| -#define DO_RS \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.storeSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - { \
|
| - ARRAY_BOUND_ERROR; \
|
| - } \
|
| - else \
|
| - args[0] = 0; \
|
| - } \
|
| - else \
|
| - args[0] = CUR.storage[I]; \
|
| - }
|
| -
|
| -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| -
|
| -
|
| -#define DO_WS \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.storeSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - { \
|
| - ARRAY_BOUND_ERROR; \
|
| - } \
|
| - } \
|
| - else \
|
| - CUR.storage[I] = args[1]; \
|
| - }
|
| -
|
| -
|
| -#define DO_RCVT \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.cvtSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - { \
|
| - ARRAY_BOUND_ERROR; \
|
| - } \
|
| - else \
|
| - args[0] = 0; \
|
| - } \
|
| - else \
|
| - args[0] = CUR_Func_read_cvt( I ); \
|
| - }
|
| -
|
| -
|
| -#define DO_WCVTP \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.cvtSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - { \
|
| - ARRAY_BOUND_ERROR; \
|
| - } \
|
| - } \
|
| - else \
|
| - CUR_Func_write_cvt( I, args[1] ); \
|
| - }
|
| -
|
| -
|
| -#define DO_WCVTF \
|
| - { \
|
| - FT_ULong I = (FT_ULong)args[0]; \
|
| - \
|
| - \
|
| - if ( BOUNDSL( I, CUR.cvtSize ) ) \
|
| - { \
|
| - if ( CUR.pedantic_hinting ) \
|
| - { \
|
| - ARRAY_BOUND_ERROR; \
|
| - } \
|
| - } \
|
| - else \
|
| - CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
|
| - }
|
| -
|
| -
|
| -#define DO_DEBUG \
|
| - CUR.error = FT_THROW( Debug_OpCode );
|
| -
|
| -
|
| -#define DO_ROUND \
|
| - args[0] = CUR_Func_round( \
|
| - args[0], \
|
| - CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
|
| -
|
| -
|
| -#define DO_NROUND \
|
| - args[0] = ROUND_None( args[0], \
|
| - CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
|
| -
|
| -
|
| -#define DO_MAX \
|
| - if ( args[1] > args[0] ) \
|
| - args[0] = args[1];
|
| -
|
| -
|
| -#define DO_MIN \
|
| - if ( args[1] < args[0] ) \
|
| - args[0] = args[1];
|
| -
|
| -
|
| -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
|
| -
|
| -
|
| -#undef ARRAY_BOUND_ERROR
|
| -#define ARRAY_BOUND_ERROR \
|
| - { \
|
| - CUR.error = FT_THROW( Invalid_Reference ); \
|
| - return; \
|
| - }
|
| + /*************************************************************************/
|
| + /* */
|
| + /* NEQ[]: Not EQual */
|
| + /* Opcode range: 0x55 */
|
| + /* Stack: StkElt StkElt --> bool */
|
| + /* */
|
| + static void
|
| + Ins_NEQ( FT_Long* args )
|
| + {
|
| + args[0] = ( args[0] != args[1] );
|
| + }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
|
| - /* Opcode range: 0x00-0x01 */
|
| - /* Stack: --> */
|
| + /* ODD[]: Is ODD */
|
| + /* Opcode range: 0x56 */
|
| + /* Stack: f26.6 --> bool */
|
| /* */
|
| static void
|
| - Ins_SVTCA( INS_ARG )
|
| + Ins_ODD( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SVTCA
|
| + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SPVTCA[a]: Set PVector to Coordinate Axis */
|
| - /* Opcode range: 0x02-0x03 */
|
| - /* Stack: --> */
|
| + /* EVEN[]: Is EVEN */
|
| + /* Opcode range: 0x57 */
|
| + /* Stack: f26.6 --> bool */
|
| /* */
|
| static void
|
| - Ins_SPVTCA( INS_ARG )
|
| + Ins_EVEN( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SPVTCA
|
| + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SFVTCA[a]: Set FVector to Coordinate Axis */
|
| - /* Opcode range: 0x04-0x05 */
|
| - /* Stack: --> */
|
| + /* AND[]: logical AND */
|
| + /* Opcode range: 0x5A */
|
| + /* Stack: uint32 uint32 --> uint32 */
|
| /* */
|
| static void
|
| - Ins_SFVTCA( INS_ARG )
|
| + Ins_AND( FT_Long* args )
|
| {
|
| - DO_SFVTCA
|
| + args[0] = ( args[0] && args[1] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SPVTL[a]: Set PVector To Line */
|
| - /* Opcode range: 0x06-0x07 */
|
| - /* Stack: uint32 uint32 --> */
|
| + /* OR[]: logical OR */
|
| + /* Opcode range: 0x5B */
|
| + /* Stack: uint32 uint32 --> uint32 */
|
| /* */
|
| static void
|
| - Ins_SPVTL( INS_ARG )
|
| + Ins_OR( FT_Long* args )
|
| {
|
| - DO_SPVTL
|
| + args[0] = ( args[0] || args[1] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SFVTL[a]: Set FVector To Line */
|
| - /* Opcode range: 0x08-0x09 */
|
| - /* Stack: uint32 uint32 --> */
|
| + /* NOT[]: logical NOT */
|
| + /* Opcode range: 0x5C */
|
| + /* Stack: StkElt --> uint32 */
|
| /* */
|
| static void
|
| - Ins_SFVTL( INS_ARG )
|
| + Ins_NOT( FT_Long* args )
|
| {
|
| - DO_SFVTL
|
| + args[0] = !args[0];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SFVTPV[]: Set FVector To PVector */
|
| - /* Opcode range: 0x0E */
|
| - /* Stack: --> */
|
| + /* ADD[]: ADD */
|
| + /* Opcode range: 0x60 */
|
| + /* Stack: f26.6 f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SFVTPV( INS_ARG )
|
| + Ins_ADD( FT_Long* args )
|
| {
|
| - DO_SFVTPV
|
| + args[0] += args[1];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SPVFS[]: Set PVector From Stack */
|
| - /* Opcode range: 0x0A */
|
| - /* Stack: f2.14 f2.14 --> */
|
| + /* SUB[]: SUBtract */
|
| + /* Opcode range: 0x61 */
|
| + /* Stack: f26.6 f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SPVFS( INS_ARG )
|
| + Ins_SUB( FT_Long* args )
|
| {
|
| - DO_SPVFS
|
| + args[0] -= args[1];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SFVFS[]: Set FVector From Stack */
|
| - /* Opcode range: 0x0B */
|
| - /* Stack: f2.14 f2.14 --> */
|
| + /* DIV[]: DIVide */
|
| + /* Opcode range: 0x62 */
|
| + /* Stack: f26.6 f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SFVFS( INS_ARG )
|
| + Ins_DIV( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SFVFS
|
| + if ( args[1] == 0 )
|
| + exc->error = FT_THROW( Divide_By_Zero );
|
| + else
|
| + args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* GPV[]: Get Projection Vector */
|
| - /* Opcode range: 0x0C */
|
| - /* Stack: ef2.14 --> ef2.14 */
|
| + /* MUL[]: MULtiply */
|
| + /* Opcode range: 0x63 */
|
| + /* Stack: f26.6 f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_GPV( INS_ARG )
|
| + Ins_MUL( FT_Long* args )
|
| {
|
| - DO_GPV
|
| + args[0] = FT_MulDiv( args[0], args[1], 64L );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| - /* GFV[]: Get Freedom Vector */
|
| - /* Opcode range: 0x0D */
|
| - /* Stack: ef2.14 --> ef2.14 */
|
| + /* */
|
| + /* ABS[]: ABSolute value */
|
| + /* Opcode range: 0x64 */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_GFV( INS_ARG )
|
| + Ins_ABS( FT_Long* args )
|
| {
|
| - DO_GFV
|
| + args[0] = FT_ABS( args[0] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SRP0[]: Set Reference Point 0 */
|
| - /* Opcode range: 0x10 */
|
| - /* Stack: uint32 --> */
|
| + /* NEG[]: NEGate */
|
| + /* Opcode range: 0x65 */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SRP0( INS_ARG )
|
| + Ins_NEG( FT_Long* args )
|
| {
|
| - DO_SRP0
|
| + args[0] = -args[0];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SRP1[]: Set Reference Point 1 */
|
| - /* Opcode range: 0x11 */
|
| - /* Stack: uint32 --> */
|
| + /* FLOOR[]: FLOOR */
|
| + /* Opcode range: 0x66 */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SRP1( INS_ARG )
|
| + Ins_FLOOR( FT_Long* args )
|
| {
|
| - DO_SRP1
|
| + args[0] = FT_PIX_FLOOR( args[0] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SRP2[]: Set Reference Point 2 */
|
| - /* Opcode range: 0x12 */
|
| - /* Stack: uint32 --> */
|
| + /* CEILING[]: CEILING */
|
| + /* Opcode range: 0x67 */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SRP2( INS_ARG )
|
| + Ins_CEILING( FT_Long* args )
|
| {
|
| - DO_SRP2
|
| + args[0] = FT_PIX_CEIL( args[0] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* RTHG[]: Round To Half Grid */
|
| - /* Opcode range: 0x19 */
|
| - /* Stack: --> */
|
| + /* RS[]: Read Store */
|
| + /* Opcode range: 0x43 */
|
| + /* Stack: uint32 --> uint32 */
|
| /* */
|
| static void
|
| - Ins_RTHG( INS_ARG )
|
| + Ins_RS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_RTHG
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| +
|
| + FT_ULong I = (FT_ULong)args[0];
|
| +
|
| +
|
| + if ( BOUNDSL( I, exc->storeSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + else
|
| + args[0] = 0;
|
| + }
|
| + else
|
| + {
|
| + /* subpixel hinting - avoid Typeman Dstroke and */
|
| + /* IStroke and Vacuform rounds */
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + ( ( I == 24 &&
|
| + ( exc->face->sph_found_func_flags &
|
| + ( SPH_FDEF_SPACING_1 |
|
| + SPH_FDEF_SPACING_2 ) ) ) ||
|
| + ( I == 22 &&
|
| + ( exc->sph_in_func_flags &
|
| + SPH_FDEF_TYPEMAN_STROKES ) ) ||
|
| + ( I == 8 &&
|
| + ( exc->face->sph_found_func_flags &
|
| + SPH_FDEF_VACUFORM_ROUND_1 ) &&
|
| + exc->iup_called ) ) )
|
| + args[0] = 0;
|
| + else
|
| + args[0] = exc->storage[I];
|
| + }
|
| +
|
| +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| +
|
| + FT_ULong I = (FT_ULong)args[0];
|
| +
|
| +
|
| + if ( BOUNDSL( I, exc->storeSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + else
|
| + args[0] = 0;
|
| + }
|
| + else
|
| + args[0] = exc->storage[I];
|
| +
|
| +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* RTG[]: Round To Grid */
|
| - /* Opcode range: 0x18 */
|
| - /* Stack: --> */
|
| + /* WS[]: Write Store */
|
| + /* Opcode range: 0x42 */
|
| + /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_RTG( INS_ARG )
|
| + Ins_WS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_RTG
|
| + FT_ULong I = (FT_ULong)args[0];
|
| +
|
| +
|
| + if ( BOUNDSL( I, exc->storeSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + }
|
| + else
|
| + exc->storage[I] = args[1];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| - /* RTDG[]: Round To Double Grid */
|
| - /* Opcode range: 0x3D */
|
| - /* Stack: --> */
|
| + /* */
|
| + /* WCVTP[]: Write CVT in Pixel units */
|
| + /* Opcode range: 0x44 */
|
| + /* Stack: f26.6 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_RTDG( INS_ARG )
|
| + Ins_WCVTP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_RTDG
|
| - }
|
| + FT_ULong I = (FT_ULong)args[0];
|
|
|
|
|
| - /*************************************************************************/
|
| - /* RUTG[]: Round Up To Grid */
|
| - /* Opcode range: 0x7C */
|
| - /* Stack: --> */
|
| - /* */
|
| - static void
|
| - Ins_RUTG( INS_ARG )
|
| - {
|
| - DO_RUTG
|
| + if ( BOUNDSL( I, exc->cvtSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + }
|
| + else
|
| + exc->func_write_cvt( exc, I, args[1] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* RDTG[]: Round Down To Grid */
|
| - /* Opcode range: 0x7D */
|
| - /* Stack: --> */
|
| + /* WCVTF[]: Write CVT in Funits */
|
| + /* Opcode range: 0x70 */
|
| + /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_RDTG( INS_ARG )
|
| + Ins_WCVTF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_RDTG
|
| + FT_ULong I = (FT_ULong)args[0];
|
| +
|
| +
|
| + if ( BOUNDSL( I, exc->cvtSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + }
|
| + else
|
| + exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* ROFF[]: Round OFF */
|
| - /* Opcode range: 0x7A */
|
| - /* Stack: --> */
|
| + /* RCVT[]: Read CVT */
|
| + /* Opcode range: 0x45 */
|
| + /* Stack: uint32 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_ROFF( INS_ARG )
|
| + Ins_RCVT( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_ROFF
|
| + FT_ULong I = (FT_ULong)args[0];
|
| +
|
| +
|
| + if ( BOUNDSL( I, exc->cvtSize ) )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + ARRAY_BOUND_ERROR;
|
| + else
|
| + args[0] = 0;
|
| + }
|
| + else
|
| + args[0] = exc->func_read_cvt( exc, I );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SROUND[]: Super ROUND */
|
| - /* Opcode range: 0x76 */
|
| - /* Stack: Eint8 --> */
|
| + /* AA[]: Adjust Angle */
|
| + /* Opcode range: 0x7F */
|
| + /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SROUND( INS_ARG )
|
| + Ins_AA( void )
|
| {
|
| - DO_SROUND
|
| + /* intentionally no longer supported */
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* S45ROUND[]: Super ROUND 45 degrees */
|
| - /* Opcode range: 0x77 */
|
| + /* DEBUG[]: DEBUG. Unsupported. */
|
| + /* Opcode range: 0x4F */
|
| /* Stack: uint32 --> */
|
| /* */
|
| + /* Note: The original instruction pops a value from the stack. */
|
| + /* */
|
| static void
|
| - Ins_S45ROUND( INS_ARG )
|
| + Ins_DEBUG( TT_ExecContext exc )
|
| {
|
| - DO_S45ROUND
|
| + exc->error = FT_THROW( Debug_OpCode );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SLOOP[]: Set LOOP variable */
|
| - /* Opcode range: 0x17 */
|
| - /* Stack: int32? --> */
|
| + /* ROUND[ab]: ROUND value */
|
| + /* Opcode range: 0x68-0x6B */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SLOOP( INS_ARG )
|
| + Ins_ROUND( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SLOOP
|
| + args[0] = exc->func_round(
|
| + exc,
|
| + args[0],
|
| + exc->tt_metrics.compensations[exc->opcode - 0x68] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SMD[]: Set Minimum Distance */
|
| - /* Opcode range: 0x1A */
|
| - /* Stack: f26.6 --> */
|
| + /* NROUND[ab]: No ROUNDing of value */
|
| + /* Opcode range: 0x6C-0x6F */
|
| + /* Stack: f26.6 --> f26.6 */
|
| /* */
|
| static void
|
| - Ins_SMD( INS_ARG )
|
| + Ins_NROUND( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SMD
|
| + args[0] = Round_None(
|
| + exc,
|
| + args[0],
|
| + exc->tt_metrics.compensations[exc->opcode - 0x6C] );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SCVTCI[]: Set Control Value Table Cut In */
|
| - /* Opcode range: 0x1D */
|
| - /* Stack: f26.6 --> */
|
| + /* MAX[]: MAXimum */
|
| + /* Opcode range: 0x68 */
|
| + /* Stack: int32? int32? --> int32 */
|
| /* */
|
| static void
|
| - Ins_SCVTCI( INS_ARG )
|
| + Ins_MAX( FT_Long* args )
|
| {
|
| - DO_SCVTCI
|
| + if ( args[1] > args[0] )
|
| + args[0] = args[1];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SSWCI[]: Set Single Width Cut In */
|
| - /* Opcode range: 0x1E */
|
| - /* Stack: f26.6 --> */
|
| + /* MIN[]: MINimum */
|
| + /* Opcode range: 0x69 */
|
| + /* Stack: int32? int32? --> int32 */
|
| /* */
|
| static void
|
| - Ins_SSWCI( INS_ARG )
|
| + Ins_MIN( FT_Long* args )
|
| {
|
| - DO_SSWCI
|
| + if ( args[1] < args[0] )
|
| + args[0] = args[1];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SSW[]: Set Single Width */
|
| - /* Opcode range: 0x1F */
|
| - /* Stack: int32? --> */
|
| + /* MINDEX[]: Move INDEXed element */
|
| + /* Opcode range: 0x26 */
|
| + /* Stack: int32? --> StkElt */
|
| /* */
|
| static void
|
| - Ins_SSW( INS_ARG )
|
| + Ins_MINDEX( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SSW
|
| + FT_Long L, K;
|
| +
|
| +
|
| + L = args[0];
|
| +
|
| + if ( L <= 0 || L > exc->args )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + }
|
| + else
|
| + {
|
| + K = exc->stack[exc->args - L];
|
| +
|
| + FT_ARRAY_MOVE( &exc->stack[exc->args - L ],
|
| + &exc->stack[exc->args - L + 1],
|
| + ( L - 1 ) );
|
| +
|
| + exc->stack[exc->args - 1] = K;
|
| + }
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* FLIPON[]: Set auto-FLIP to ON */
|
| - /* Opcode range: 0x4D */
|
| - /* Stack: --> */
|
| + /* CINDEX[]: Copy INDEXed element */
|
| + /* Opcode range: 0x25 */
|
| + /* Stack: int32 --> StkElt */
|
| /* */
|
| static void
|
| - Ins_FLIPON( INS_ARG )
|
| + Ins_CINDEX( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_FLIPON
|
| + FT_Long L;
|
| +
|
| +
|
| + L = args[0];
|
| +
|
| + if ( L <= 0 || L > exc->args )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + args[0] = 0;
|
| + }
|
| + else
|
| + args[0] = exc->stack[exc->args - L];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* FLIPOFF[]: Set auto-FLIP to OFF */
|
| - /* Opcode range: 0x4E */
|
| - /* Stack: --> */
|
| + /* ROLL[]: ROLL top three elements */
|
| + /* Opcode range: 0x8A */
|
| + /* Stack: 3 * StkElt --> 3 * StkElt */
|
| /* */
|
| static void
|
| - Ins_FLIPOFF( INS_ARG )
|
| + Ins_ROLL( FT_Long* args )
|
| {
|
| - DO_FLIPOFF
|
| + FT_Long A, B, C;
|
| +
|
| +
|
| + A = args[2];
|
| + B = args[1];
|
| + C = args[0];
|
| +
|
| + args[2] = C;
|
| + args[1] = A;
|
| + args[0] = B;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SANGW[]: Set ANGle Weight */
|
| - /* Opcode range: 0x7E */
|
| - /* Stack: uint32 --> */
|
| + /* MANAGING THE FLOW OF CONTROL */
|
| /* */
|
| - static void
|
| - Ins_SANGW( INS_ARG )
|
| - {
|
| - /* instruction not supported anymore */
|
| - }
|
| + /*************************************************************************/
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SDB[]: Set Delta Base */
|
| - /* Opcode range: 0x5E */
|
| - /* Stack: uint32 --> */
|
| + /* SLOOP[]: Set LOOP variable */
|
| + /* Opcode range: 0x17 */
|
| + /* Stack: int32? --> */
|
| /* */
|
| static void
|
| - Ins_SDB( INS_ARG )
|
| + Ins_SLOOP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SDB
|
| + if ( args[0] < 0 )
|
| + exc->error = FT_THROW( Bad_Argument );
|
| + else
|
| + exc->GS.loop = args[0];
|
| }
|
|
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* SDS[]: Set Delta Shift */
|
| - /* Opcode range: 0x5F */
|
| - /* Stack: uint32 --> */
|
| - /* */
|
| - static void
|
| - Ins_SDS( INS_ARG )
|
| + static FT_Bool
|
| + SkipCode( TT_ExecContext exc )
|
| {
|
| - DO_SDS
|
| + exc->IP += exc->length;
|
| +
|
| + if ( exc->IP < exc->codeSize )
|
| + {
|
| + exc->opcode = exc->code[exc->IP];
|
| +
|
| + exc->length = opcode_length[exc->opcode];
|
| + if ( exc->length < 0 )
|
| + {
|
| + if ( exc->IP + 1 >= exc->codeSize )
|
| + goto Fail_Overflow;
|
| + exc->length = 2 - exc->length * exc->code[exc->IP + 1];
|
| + }
|
| +
|
| + if ( exc->IP + exc->length <= exc->codeSize )
|
| + return SUCCESS;
|
| + }
|
| +
|
| + Fail_Overflow:
|
| + exc->error = FT_THROW( Code_Overflow );
|
| + return FAILURE;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* MPPEM[]: Measure Pixel Per EM */
|
| - /* Opcode range: 0x4B */
|
| - /* Stack: --> Euint16 */
|
| + /* IF[]: IF test */
|
| + /* Opcode range: 0x58 */
|
| + /* Stack: StkElt --> */
|
| /* */
|
| static void
|
| - Ins_MPPEM( INS_ARG )
|
| + Ins_IF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_MPPEM
|
| + FT_Int nIfs;
|
| + FT_Bool Out;
|
| +
|
| +
|
| + if ( args[0] != 0 )
|
| + return;
|
| +
|
| + nIfs = 1;
|
| + Out = 0;
|
| +
|
| + do
|
| + {
|
| + if ( SkipCode( exc ) == FAILURE )
|
| + return;
|
| +
|
| + switch ( exc->opcode )
|
| + {
|
| + case 0x58: /* IF */
|
| + nIfs++;
|
| + break;
|
| +
|
| + case 0x1B: /* ELSE */
|
| + Out = FT_BOOL( nIfs == 1 );
|
| + break;
|
| +
|
| + case 0x59: /* EIF */
|
| + nIfs--;
|
| + Out = FT_BOOL( nIfs == 0 );
|
| + break;
|
| + }
|
| + } while ( Out == 0 );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* MPS[]: Measure Point Size */
|
| - /* Opcode range: 0x4C */
|
| - /* Stack: --> Euint16 */
|
| + /* ELSE[]: ELSE */
|
| + /* Opcode range: 0x1B */
|
| + /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_MPS( INS_ARG )
|
| + Ins_ELSE( TT_ExecContext exc )
|
| {
|
| - DO_MPS
|
| + FT_Int nIfs;
|
| +
|
| +
|
| + nIfs = 1;
|
| +
|
| + do
|
| + {
|
| + if ( SkipCode( exc ) == FAILURE )
|
| + return;
|
| +
|
| + switch ( exc->opcode )
|
| + {
|
| + case 0x58: /* IF */
|
| + nIfs++;
|
| + break;
|
| +
|
| + case 0x59: /* EIF */
|
| + nIfs--;
|
| + break;
|
| + }
|
| + } while ( nIfs != 0 );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* DUP[]: DUPlicate the top stack's element */
|
| - /* Opcode range: 0x20 */
|
| - /* Stack: StkElt --> StkElt StkElt */
|
| + /* EIF[]: End IF */
|
| + /* Opcode range: 0x59 */
|
| + /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_DUP( INS_ARG )
|
| + Ins_EIF( void )
|
| {
|
| - DO_DUP
|
| + /* nothing to do */
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* POP[]: POP the stack's top element */
|
| - /* Opcode range: 0x21 */
|
| - /* Stack: StkElt --> */
|
| + /* JMPR[]: JuMP Relative */
|
| + /* Opcode range: 0x1C */
|
| + /* Stack: int32 --> */
|
| /* */
|
| static void
|
| - Ins_POP( INS_ARG )
|
| + Ins_JMPR( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - /* nothing to do */
|
| + if ( args[0] == 0 && exc->args == 0 )
|
| + exc->error = FT_THROW( Bad_Argument );
|
| + exc->IP += args[0];
|
| + if ( exc->IP < 0 ||
|
| + ( exc->callTop > 0 &&
|
| + exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
|
| + exc->error = FT_THROW( Bad_Argument );
|
| + exc->step_ins = FALSE;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* CLEAR[]: CLEAR the entire stack */
|
| - /* Opcode range: 0x22 */
|
| - /* Stack: StkElt... --> */
|
| + /* JROT[]: Jump Relative On True */
|
| + /* Opcode range: 0x78 */
|
| + /* Stack: StkElt int32 --> */
|
| /* */
|
| static void
|
| - Ins_CLEAR( INS_ARG )
|
| + Ins_JROT( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_CLEAR
|
| + if ( args[1] != 0 )
|
| + Ins_JMPR( exc, args );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SWAP[]: SWAP the stack's top two elements */
|
| - /* Opcode range: 0x23 */
|
| - /* Stack: 2 * StkElt --> 2 * StkElt */
|
| + /* JROF[]: Jump Relative On False */
|
| + /* Opcode range: 0x79 */
|
| + /* Stack: StkElt int32 --> */
|
| /* */
|
| static void
|
| - Ins_SWAP( INS_ARG )
|
| + Ins_JROF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_SWAP
|
| + if ( args[1] == 0 )
|
| + Ins_JMPR( exc, args );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* DEPTH[]: return the stack DEPTH */
|
| - /* Opcode range: 0x24 */
|
| - /* Stack: --> uint32 */
|
| + /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
|
| /* */
|
| - static void
|
| - Ins_DEPTH( INS_ARG )
|
| - {
|
| - DO_DEPTH
|
| - }
|
| + /*************************************************************************/
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* CINDEX[]: Copy INDEXed element */
|
| - /* Opcode range: 0x25 */
|
| - /* Stack: int32 --> StkElt */
|
| - /* */
|
| - static void
|
| - Ins_CINDEX( INS_ARG )
|
| - {
|
| - DO_CINDEX
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* EIF[]: End IF */
|
| - /* Opcode range: 0x59 */
|
| - /* Stack: --> */
|
| - /* */
|
| - static void
|
| - Ins_EIF( INS_ARG )
|
| - {
|
| - /* nothing to do */
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* JROT[]: Jump Relative On True */
|
| - /* Opcode range: 0x78 */
|
| - /* Stack: StkElt int32 --> */
|
| - /* */
|
| - static void
|
| - Ins_JROT( INS_ARG )
|
| - {
|
| - DO_JROT
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* JMPR[]: JuMP Relative */
|
| - /* Opcode range: 0x1C */
|
| - /* Stack: int32 --> */
|
| - /* */
|
| - static void
|
| - Ins_JMPR( INS_ARG )
|
| - {
|
| - DO_JMPR
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* JROF[]: Jump Relative On False */
|
| - /* Opcode range: 0x79 */
|
| - /* Stack: StkElt int32 --> */
|
| - /* */
|
| - static void
|
| - Ins_JROF( INS_ARG )
|
| - {
|
| - DO_JROF
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* LT[]: Less Than */
|
| - /* Opcode range: 0x50 */
|
| - /* Stack: int32? int32? --> bool */
|
| - /* */
|
| - static void
|
| - Ins_LT( INS_ARG )
|
| - {
|
| - DO_LT
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* LTEQ[]: Less Than or EQual */
|
| - /* Opcode range: 0x51 */
|
| - /* Stack: int32? int32? --> bool */
|
| - /* */
|
| - static void
|
| - Ins_LTEQ( INS_ARG )
|
| - {
|
| - DO_LTEQ
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* GT[]: Greater Than */
|
| - /* Opcode range: 0x52 */
|
| - /* Stack: int32? int32? --> bool */
|
| - /* */
|
| - static void
|
| - Ins_GT( INS_ARG )
|
| - {
|
| - DO_GT
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* GTEQ[]: Greater Than or EQual */
|
| - /* Opcode range: 0x53 */
|
| - /* Stack: int32? int32? --> bool */
|
| - /* */
|
| - static void
|
| - Ins_GTEQ( INS_ARG )
|
| - {
|
| - DO_GTEQ
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* EQ[]: EQual */
|
| - /* Opcode range: 0x54 */
|
| - /* Stack: StkElt StkElt --> bool */
|
| - /* */
|
| - static void
|
| - Ins_EQ( INS_ARG )
|
| - {
|
| - DO_EQ
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* NEQ[]: Not EQual */
|
| - /* Opcode range: 0x55 */
|
| - /* Stack: StkElt StkElt --> bool */
|
| - /* */
|
| - static void
|
| - Ins_NEQ( INS_ARG )
|
| - {
|
| - DO_NEQ
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ODD[]: Is ODD */
|
| - /* Opcode range: 0x56 */
|
| - /* Stack: f26.6 --> bool */
|
| - /* */
|
| - static void
|
| - Ins_ODD( INS_ARG )
|
| - {
|
| - DO_ODD
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* EVEN[]: Is EVEN */
|
| - /* Opcode range: 0x57 */
|
| - /* Stack: f26.6 --> bool */
|
| - /* */
|
| - static void
|
| - Ins_EVEN( INS_ARG )
|
| - {
|
| - DO_EVEN
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* AND[]: logical AND */
|
| - /* Opcode range: 0x5A */
|
| - /* Stack: uint32 uint32 --> uint32 */
|
| - /* */
|
| - static void
|
| - Ins_AND( INS_ARG )
|
| - {
|
| - DO_AND
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* OR[]: logical OR */
|
| - /* Opcode range: 0x5B */
|
| - /* Stack: uint32 uint32 --> uint32 */
|
| - /* */
|
| - static void
|
| - Ins_OR( INS_ARG )
|
| - {
|
| - DO_OR
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* NOT[]: logical NOT */
|
| - /* Opcode range: 0x5C */
|
| - /* Stack: StkElt --> uint32 */
|
| - /* */
|
| - static void
|
| - Ins_NOT( INS_ARG )
|
| - {
|
| - DO_NOT
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ADD[]: ADD */
|
| - /* Opcode range: 0x60 */
|
| - /* Stack: f26.6 f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_ADD( INS_ARG )
|
| - {
|
| - DO_ADD
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* SUB[]: SUBtract */
|
| - /* Opcode range: 0x61 */
|
| - /* Stack: f26.6 f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_SUB( INS_ARG )
|
| - {
|
| - DO_SUB
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* DIV[]: DIVide */
|
| - /* Opcode range: 0x62 */
|
| - /* Stack: f26.6 f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_DIV( INS_ARG )
|
| - {
|
| - DO_DIV
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* MUL[]: MULtiply */
|
| - /* Opcode range: 0x63 */
|
| - /* Stack: f26.6 f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_MUL( INS_ARG )
|
| - {
|
| - DO_MUL
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ABS[]: ABSolute value */
|
| - /* Opcode range: 0x64 */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_ABS( INS_ARG )
|
| - {
|
| - DO_ABS
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* NEG[]: NEGate */
|
| - /* Opcode range: 0x65 */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_NEG( INS_ARG )
|
| - {
|
| - DO_NEG
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* FLOOR[]: FLOOR */
|
| - /* Opcode range: 0x66 */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_FLOOR( INS_ARG )
|
| - {
|
| - DO_FLOOR
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* CEILING[]: CEILING */
|
| - /* Opcode range: 0x67 */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_CEILING( INS_ARG )
|
| - {
|
| - DO_CEILING
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* RS[]: Read Store */
|
| - /* Opcode range: 0x43 */
|
| - /* Stack: uint32 --> uint32 */
|
| - /* */
|
| - static void
|
| - Ins_RS( INS_ARG )
|
| - {
|
| - DO_RS
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* WS[]: Write Store */
|
| - /* Opcode range: 0x42 */
|
| - /* Stack: uint32 uint32 --> */
|
| - /* */
|
| - static void
|
| - Ins_WS( INS_ARG )
|
| - {
|
| - DO_WS
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* WCVTP[]: Write CVT in Pixel units */
|
| - /* Opcode range: 0x44 */
|
| - /* Stack: f26.6 uint32 --> */
|
| - /* */
|
| - static void
|
| - Ins_WCVTP( INS_ARG )
|
| - {
|
| - DO_WCVTP
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* WCVTF[]: Write CVT in Funits */
|
| - /* Opcode range: 0x70 */
|
| - /* Stack: uint32 uint32 --> */
|
| - /* */
|
| - static void
|
| - Ins_WCVTF( INS_ARG )
|
| - {
|
| - DO_WCVTF
|
| - }
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* RCVT[]: Read CVT */
|
| - /* Opcode range: 0x45 */
|
| - /* Stack: uint32 --> f26.6 */
|
| + /* FDEF[]: Function DEFinition */
|
| + /* Opcode range: 0x2C */
|
| + /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_RCVT( INS_ARG )
|
| + Ins_FDEF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - DO_RCVT
|
| - }
|
| + FT_ULong n;
|
| + TT_DefRecord* rec;
|
| + TT_DefRecord* limit;
|
|
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + /* arguments to opcodes are skipped by `SKIP_Code' */
|
| + FT_Byte opcode_pattern[9][12] = {
|
| + /* #0 inline delta function 1 */
|
| + {
|
| + 0x4B, /* PPEM */
|
| + 0x53, /* GTEQ */
|
| + 0x23, /* SWAP */
|
| + 0x4B, /* PPEM */
|
| + 0x51, /* LTEQ */
|
| + 0x5A, /* AND */
|
| + 0x58, /* IF */
|
| + 0x38, /* SHPIX */
|
| + 0x1B, /* ELSE */
|
| + 0x21, /* POP */
|
| + 0x21, /* POP */
|
| + 0x59 /* EIF */
|
| + },
|
| + /* #1 inline delta function 2 */
|
| + {
|
| + 0x4B, /* PPEM */
|
| + 0x54, /* EQ */
|
| + 0x58, /* IF */
|
| + 0x38, /* SHPIX */
|
| + 0x1B, /* ELSE */
|
| + 0x21, /* POP */
|
| + 0x21, /* POP */
|
| + 0x59 /* EIF */
|
| + },
|
| + /* #2 diagonal stroke function */
|
| + {
|
| + 0x20, /* DUP */
|
| + 0x20, /* DUP */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 1 */
|
| + 0x60, /* ADD */
|
| + 0x46, /* GC_cur */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 64 */
|
| + 0x23, /* SWAP */
|
| + 0x42 /* WS */
|
| + },
|
| + /* #3 VacuFormRound function */
|
| + {
|
| + 0x45, /* RCVT */
|
| + 0x23, /* SWAP */
|
| + 0x46, /* GC_cur */
|
| + 0x60, /* ADD */
|
| + 0x20, /* DUP */
|
| + 0xB0 /* PUSHB_1 */
|
| + /* 38 */
|
| + },
|
| + /* #4 TTFautohint bytecode (old) */
|
| + {
|
| + 0x20, /* DUP */
|
| + 0x64, /* ABS */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 32 */
|
| + 0x60, /* ADD */
|
| + 0x66, /* FLOOR */
|
| + 0x23, /* SWAP */
|
| + 0xB0 /* PUSHB_1 */
|
| + },
|
| + /* #5 spacing function 1 */
|
| + {
|
| + 0x01, /* SVTCA_x */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 24 */
|
| + 0x43, /* RS */
|
| + 0x58 /* IF */
|
| + },
|
| + /* #6 spacing function 2 */
|
| + {
|
| + 0x01, /* SVTCA_x */
|
| + 0x18, /* RTG */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 24 */
|
| + 0x43, /* RS */
|
| + 0x58 /* IF */
|
| + },
|
| + /* #7 TypeMan Talk DiagEndCtrl function */
|
| + {
|
| + 0x01, /* SVTCA_x */
|
| + 0x20, /* DUP */
|
| + 0xB0, /* PUSHB_1 */
|
| + /* 3 */
|
| + 0x25, /* CINDEX */
|
| + },
|
| + /* #8 TypeMan Talk Align */
|
| + {
|
| + 0x06, /* SPVTL */
|
| + 0x7D, /* RDTG */
|
| + },
|
| + };
|
| + FT_UShort opcode_patterns = 9;
|
| + FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
| + FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
|
| + FT_UShort i;
|
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* AA[]: Adjust Angle */
|
| - /* Opcode range: 0x7F */
|
| - /* Stack: uint32 --> */
|
| - /* */
|
| - static void
|
| - Ins_AA( INS_ARG )
|
| - {
|
| - /* intentionally no longer supported */
|
| - }
|
|
|
| + /* some font programs are broken enough to redefine functions! */
|
| + /* We will then parse the current table. */
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* DEBUG[]: DEBUG. Unsupported. */
|
| - /* Opcode range: 0x4F */
|
| - /* Stack: uint32 --> */
|
| - /* */
|
| - /* Note: The original instruction pops a value from the stack. */
|
| - /* */
|
| - static void
|
| - Ins_DEBUG( INS_ARG )
|
| - {
|
| - DO_DEBUG
|
| - }
|
| + rec = exc->FDefs;
|
| + limit = rec + exc->numFDefs;
|
| + n = (FT_ULong)args[0];
|
|
|
| + for ( ; rec < limit; rec++ )
|
| + {
|
| + if ( rec->opc == n )
|
| + break;
|
| + }
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ROUND[ab]: ROUND value */
|
| - /* Opcode range: 0x68-0x6B */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_ROUND( INS_ARG )
|
| - {
|
| - DO_ROUND
|
| - }
|
| + if ( rec == limit )
|
| + {
|
| + /* check that there is enough room for new functions */
|
| + if ( exc->numFDefs >= exc->maxFDefs )
|
| + {
|
| + exc->error = FT_THROW( Too_Many_Function_Defs );
|
| + return;
|
| + }
|
| + exc->numFDefs++;
|
| + }
|
|
|
| + /* Although FDEF takes unsigned 32-bit integer, */
|
| + /* func # must be within unsigned 16-bit integer */
|
| + if ( n > 0xFFFFU )
|
| + {
|
| + exc->error = FT_THROW( Too_Many_Function_Defs );
|
| + return;
|
| + }
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* NROUND[ab]: No ROUNDing of value */
|
| - /* Opcode range: 0x6C-0x6F */
|
| - /* Stack: f26.6 --> f26.6 */
|
| - /* */
|
| - static void
|
| - Ins_NROUND( INS_ARG )
|
| - {
|
| - DO_NROUND
|
| - }
|
| + rec->range = exc->curRange;
|
| + rec->opc = (FT_UInt16)n;
|
| + rec->start = exc->IP + 1;
|
| + rec->active = TRUE;
|
| + rec->inline_delta = FALSE;
|
| + rec->sph_fdef_flags = 0x0000;
|
|
|
| + if ( n > exc->maxFunc )
|
| + exc->maxFunc = (FT_UInt16)n;
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* MAX[]: MAXimum */
|
| - /* Opcode range: 0x68 */
|
| - /* Stack: int32? int32? --> int32 */
|
| - /* */
|
| - static void
|
| - Ins_MAX( INS_ARG )
|
| - {
|
| - DO_MAX
|
| - }
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + /* We don't know for sure these are typeman functions, */
|
| + /* however they are only active when RS 22 is called */
|
| + if ( n >= 64 && n <= 66 )
|
| + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
|
| +#endif
|
|
|
| + /* Now skip the whole function definition. */
|
| + /* We don't allow nested IDEFS & FDEFs. */
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* MIN[]: MINimum */
|
| - /* Opcode range: 0x69 */
|
| - /* Stack: int32? int32? --> int32 */
|
| - /* */
|
| - static void
|
| - Ins_MIN( INS_ARG )
|
| - {
|
| - DO_MIN
|
| - }
|
| + while ( SkipCode( exc ) == SUCCESS )
|
| + {
|
|
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
|
| + if ( SUBPIXEL_HINTING )
|
| + {
|
| + for ( i = 0; i < opcode_patterns; i++ )
|
| + {
|
| + if ( opcode_pointer[i] < opcode_size[i] &&
|
| + exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
|
| + {
|
| + opcode_pointer[i] += 1;
|
|
|
| + if ( opcode_pointer[i] == opcode_size[i] )
|
| + {
|
| + FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
|
| + i, n,
|
| + exc->face->root.family_name,
|
| + exc->face->root.style_name ));
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* The following functions are called as is within the switch statement. */
|
| - /* */
|
| - /*************************************************************************/
|
| + switch ( i )
|
| + {
|
| + case 0:
|
| + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
|
| + break;
|
|
|
| + case 1:
|
| + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
|
| + break;
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* MINDEX[]: Move INDEXed element */
|
| - /* Opcode range: 0x26 */
|
| - /* Stack: int32? --> StkElt */
|
| - /* */
|
| - static void
|
| - Ins_MINDEX( INS_ARG )
|
| - {
|
| - FT_Long L, K;
|
| + case 2:
|
| + switch ( n )
|
| + {
|
| + /* needs to be implemented still */
|
| + case 58:
|
| + rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
|
| + }
|
| + break;
|
|
|
| + case 3:
|
| + switch ( n )
|
| + {
|
| + case 0:
|
| + rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
|
| + }
|
| + break;
|
|
|
| - L = args[0];
|
| + case 4:
|
| + /* probably not necessary to detect anymore */
|
| + rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
|
| + break;
|
|
|
| - if ( L <= 0 || L > CUR.args )
|
| - {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| - }
|
| - else
|
| - {
|
| - K = CUR.stack[CUR.args - L];
|
| + case 5:
|
| + switch ( n )
|
| + {
|
| + case 0:
|
| + case 1:
|
| + case 2:
|
| + case 4:
|
| + case 7:
|
| + case 8:
|
| + rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
|
| + }
|
| + break;
|
|
|
| - FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ],
|
| - &CUR.stack[CUR.args - L + 1],
|
| - ( L - 1 ) );
|
| + case 6:
|
| + switch ( n )
|
| + {
|
| + case 0:
|
| + case 1:
|
| + case 2:
|
| + case 4:
|
| + case 7:
|
| + case 8:
|
| + rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
|
| + }
|
| + break;
|
|
|
| - CUR.stack[CUR.args - 1] = K;
|
| - }
|
| - }
|
| + case 7:
|
| + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| + break;
|
|
|
| + case 8:
|
| +#if 0
|
| + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| +#endif
|
| + break;
|
| + }
|
| + opcode_pointer[i] = 0;
|
| + }
|
| + }
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ROLL[]: ROLL top three elements */
|
| - /* Opcode range: 0x8A */
|
| - /* Stack: 3 * StkElt --> 3 * StkElt */
|
| - /* */
|
| - static void
|
| - Ins_ROLL( INS_ARG )
|
| - {
|
| - FT_Long A, B, C;
|
| + else
|
| + opcode_pointer[i] = 0;
|
| + }
|
|
|
| - FT_UNUSED_EXEC;
|
| + /* Set sph_compatibility_mode only when deltas are detected */
|
| + exc->face->sph_compatibility_mode =
|
| + ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
|
| + ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
|
| + }
|
|
|
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - A = args[2];
|
| - B = args[1];
|
| - C = args[0];
|
| + switch ( exc->opcode )
|
| + {
|
| + case 0x89: /* IDEF */
|
| + case 0x2C: /* FDEF */
|
| + exc->error = FT_THROW( Nested_DEFS );
|
| + return;
|
|
|
| - args[2] = C;
|
| - args[1] = A;
|
| - args[0] = B;
|
| + case 0x2D: /* ENDF */
|
| + rec->end = exc->IP;
|
| + return;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* MANAGING THE FLOW OF CONTROL */
|
| - /* */
|
| - /* Instructions appear in the specification's order. */
|
| + /* ENDF[]: END Function definition */
|
| + /* Opcode range: 0x2D */
|
| + /* Stack: --> */
|
| /* */
|
| - /*************************************************************************/
|
| + static void
|
| + Ins_ENDF( TT_ExecContext exc )
|
| + {
|
| + TT_CallRec* pRec;
|
|
|
|
|
| - static FT_Bool
|
| - SkipCode( EXEC_OP )
|
| - {
|
| - CUR.IP += CUR.length;
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + exc->sph_in_func_flags = 0x0000;
|
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - if ( CUR.IP < CUR.codeSize )
|
| + if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */
|
| {
|
| - CUR.opcode = CUR.code[CUR.IP];
|
| + exc->error = FT_THROW( ENDF_In_Exec_Stream );
|
| + return;
|
| + }
|
|
|
| - CUR.length = opcode_length[CUR.opcode];
|
| - if ( CUR.length < 0 )
|
| - {
|
| - if ( CUR.IP + 1 >= CUR.codeSize )
|
| - goto Fail_Overflow;
|
| - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
|
| - }
|
| + exc->callTop--;
|
|
|
| - if ( CUR.IP + CUR.length <= CUR.codeSize )
|
| - return SUCCESS;
|
| + pRec = &exc->callStack[exc->callTop];
|
| +
|
| + pRec->Cur_Count--;
|
| +
|
| + exc->step_ins = FALSE;
|
| +
|
| + if ( pRec->Cur_Count > 0 )
|
| + {
|
| + exc->callTop++;
|
| + exc->IP = pRec->Def->start;
|
| }
|
| + else
|
| + /* Loop through the current function */
|
| + Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP );
|
|
|
| - Fail_Overflow:
|
| - CUR.error = FT_THROW( Code_Overflow );
|
| - return FAILURE;
|
| + /* Exit the current call frame. */
|
| +
|
| + /* NOTE: If the last instruction of a program is a */
|
| + /* CALL or LOOPCALL, the return address is */
|
| + /* always out of the code range. This is a */
|
| + /* valid address, and it is why we do not test */
|
| + /* the result of Ins_Goto_CodeRange() here! */
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* IF[]: IF test */
|
| - /* Opcode range: 0x58 */
|
| - /* Stack: StkElt --> */
|
| + /* CALL[]: CALL function */
|
| + /* Opcode range: 0x2B */
|
| + /* Stack: uint32? --> */
|
| /* */
|
| static void
|
| - Ins_IF( INS_ARG )
|
| + Ins_CALL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - FT_Int nIfs;
|
| - FT_Bool Out;
|
| + FT_ULong F;
|
| + TT_CallRec* pCrec;
|
| + TT_DefRecord* def;
|
|
|
|
|
| - if ( args[0] != 0 )
|
| - return;
|
| + /* first of all, check the index */
|
|
|
| - nIfs = 1;
|
| - Out = 0;
|
| + F = (FT_ULong)args[0];
|
| + if ( BOUNDSL( F, exc->maxFunc + 1 ) )
|
| + goto Fail;
|
|
|
| - do
|
| + /* Except for some old Apple fonts, all functions in a TrueType */
|
| + /* font are defined in increasing order, starting from 0. This */
|
| + /* means that we normally have */
|
| + /* */
|
| + /* exc->maxFunc+1 == exc->numFDefs */
|
| + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
|
| + /* */
|
| + /* If this isn't true, we need to look up the function table. */
|
| +
|
| + def = exc->FDefs + F;
|
| + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
|
| {
|
| - if ( SKIP_Code() == FAILURE )
|
| - return;
|
| + /* look up the FDefs table */
|
| + TT_DefRecord* limit;
|
|
|
| - switch ( CUR.opcode )
|
| - {
|
| - case 0x58: /* IF */
|
| - nIfs++;
|
| - break;
|
|
|
| - case 0x1B: /* ELSE */
|
| - Out = FT_BOOL( nIfs == 1 );
|
| - break;
|
| + def = exc->FDefs;
|
| + limit = def + exc->numFDefs;
|
|
|
| - case 0x59: /* EIF */
|
| - nIfs--;
|
| - Out = FT_BOOL( nIfs == 0 );
|
| - break;
|
| - }
|
| - } while ( Out == 0 );
|
| - }
|
| + while ( def < limit && def->opc != F )
|
| + def++;
|
|
|
| + if ( def == limit )
|
| + goto Fail;
|
| + }
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* ELSE[]: ELSE */
|
| - /* Opcode range: 0x1B */
|
| - /* Stack: --> */
|
| - /* */
|
| - static void
|
| - Ins_ELSE( INS_ARG )
|
| - {
|
| - FT_Int nIfs;
|
| + /* check that the function is active */
|
| + if ( !def->active )
|
| + goto Fail;
|
|
|
| - FT_UNUSED_ARG;
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + ( ( exc->iup_called &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
|
| + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
|
| + goto Fail;
|
| + else
|
| + exc->sph_in_func_flags = def->sph_fdef_flags;
|
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| + /* check the call stack */
|
| + if ( exc->callTop >= exc->callSize )
|
| + {
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| + }
|
|
|
| - nIfs = 1;
|
| + pCrec = exc->callStack + exc->callTop;
|
|
|
| - do
|
| - {
|
| - if ( SKIP_Code() == FAILURE )
|
| - return;
|
| + pCrec->Caller_Range = exc->curRange;
|
| + pCrec->Caller_IP = exc->IP + 1;
|
| + pCrec->Cur_Count = 1;
|
| + pCrec->Def = def;
|
|
|
| - switch ( CUR.opcode )
|
| - {
|
| - case 0x58: /* IF */
|
| - nIfs++;
|
| - break;
|
| + exc->callTop++;
|
|
|
| - case 0x59: /* EIF */
|
| - nIfs--;
|
| - break;
|
| - }
|
| - } while ( nIfs != 0 );
|
| - }
|
| + Ins_Goto_CodeRange( exc, def->range, def->start );
|
|
|
| + exc->step_ins = FALSE;
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
|
| - /* */
|
| - /* Instructions appear in the specification's order. */
|
| - /* */
|
| - /*************************************************************************/
|
| + return;
|
| +
|
| + Fail:
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* FDEF[]: Function DEFinition */
|
| - /* Opcode range: 0x2C */
|
| - /* Stack: uint32 --> */
|
| + /* LOOPCALL[]: LOOP and CALL function */
|
| + /* Opcode range: 0x2A */
|
| + /* Stack: uint32? Eint16? --> */
|
| /* */
|
| static void
|
| - Ins_FDEF( INS_ARG )
|
| + Ins_LOOPCALL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - FT_ULong n;
|
| - TT_DefRecord* rec;
|
| - TT_DefRecord* limit;
|
| + FT_ULong F;
|
| + TT_CallRec* pCrec;
|
| + TT_DefRecord* def;
|
|
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - /* arguments to opcodes are skipped by `SKIP_Code' */
|
| - FT_Byte opcode_pattern[9][12] = {
|
| - /* #0 inline delta function 1 */
|
| - {
|
| - 0x4B, /* PPEM */
|
| - 0x53, /* GTEQ */
|
| - 0x23, /* SWAP */
|
| - 0x4B, /* PPEM */
|
| - 0x51, /* LTEQ */
|
| - 0x5A, /* AND */
|
| - 0x58, /* IF */
|
| - 0x38, /* SHPIX */
|
| - 0x1B, /* ELSE */
|
| - 0x21, /* POP */
|
| - 0x21, /* POP */
|
| - 0x59 /* EIF */
|
| - },
|
| - /* #1 inline delta function 2 */
|
| - {
|
| - 0x4B, /* PPEM */
|
| - 0x54, /* EQ */
|
| - 0x58, /* IF */
|
| - 0x38, /* SHPIX */
|
| - 0x1B, /* ELSE */
|
| - 0x21, /* POP */
|
| - 0x21, /* POP */
|
| - 0x59 /* EIF */
|
| - },
|
| - /* #2 diagonal stroke function */
|
| - {
|
| - 0x20, /* DUP */
|
| - 0x20, /* DUP */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 1 */
|
| - 0x60, /* ADD */
|
| - 0x46, /* GC_cur */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 64 */
|
| - 0x23, /* SWAP */
|
| - 0x42 /* WS */
|
| - },
|
| - /* #3 VacuFormRound function */
|
| - {
|
| - 0x45, /* RCVT */
|
| - 0x23, /* SWAP */
|
| - 0x46, /* GC_cur */
|
| - 0x60, /* ADD */
|
| - 0x20, /* DUP */
|
| - 0xB0 /* PUSHB_1 */
|
| - /* 38 */
|
| - },
|
| - /* #4 TTFautohint bytecode (old) */
|
| - {
|
| - 0x20, /* DUP */
|
| - 0x64, /* ABS */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 32 */
|
| - 0x60, /* ADD */
|
| - 0x66, /* FLOOR */
|
| - 0x23, /* SWAP */
|
| - 0xB0 /* PUSHB_1 */
|
| - },
|
| - /* #5 spacing function 1 */
|
| - {
|
| - 0x01, /* SVTCA_x */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 24 */
|
| - 0x43, /* RS */
|
| - 0x58 /* IF */
|
| - },
|
| - /* #6 spacing function 2 */
|
| - {
|
| - 0x01, /* SVTCA_x */
|
| - 0x18, /* RTG */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 24 */
|
| - 0x43, /* RS */
|
| - 0x58 /* IF */
|
| - },
|
| - /* #7 TypeMan Talk DiagEndCtrl function */
|
| - {
|
| - 0x01, /* SVTCA_x */
|
| - 0x20, /* DUP */
|
| - 0xB0, /* PUSHB_1 */
|
| - /* 3 */
|
| - 0x25, /* CINDEX */
|
| - },
|
| - /* #8 TypeMan Talk Align */
|
| - {
|
| - 0x06, /* SPVTL */
|
| - 0x7D, /* RDTG */
|
| - },
|
| - };
|
| - FT_UShort opcode_patterns = 9;
|
| - FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
| - FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
|
| - FT_UShort i;
|
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| +
|
| + /* first of all, check the index */
|
| + F = (FT_ULong)args[1];
|
| + if ( BOUNDSL( F, exc->maxFunc + 1 ) )
|
| + goto Fail;
|
| +
|
| + /* Except for some old Apple fonts, all functions in a TrueType */
|
| + /* font are defined in increasing order, starting from 0. This */
|
| + /* means that we normally have */
|
| + /* */
|
| + /* exc->maxFunc+1 == exc->numFDefs */
|
| + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
|
| + /* */
|
| + /* If this isn't true, we need to look up the function table. */
|
| +
|
| + def = exc->FDefs + F;
|
| + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
|
| + {
|
| + /* look up the FDefs table */
|
| + TT_DefRecord* limit;
|
|
|
|
|
| - /* some font programs are broken enough to redefine functions! */
|
| - /* We will then parse the current table. */
|
| + def = exc->FDefs;
|
| + limit = def + exc->numFDefs;
|
|
|
| - rec = CUR.FDefs;
|
| - limit = rec + CUR.numFDefs;
|
| - n = args[0];
|
| + while ( def < limit && def->opc != F )
|
| + def++;
|
|
|
| - for ( ; rec < limit; rec++ )
|
| + if ( def == limit )
|
| + goto Fail;
|
| + }
|
| +
|
| + /* check that the function is active */
|
| + if ( !def->active )
|
| + goto Fail;
|
| +
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
|
| + goto Fail;
|
| + else
|
| + exc->sph_in_func_flags = def->sph_fdef_flags;
|
| +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| +
|
| + /* check stack */
|
| + if ( exc->callTop >= exc->callSize )
|
| {
|
| - if ( rec->opc == n )
|
| - break;
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| }
|
|
|
| - if ( rec == limit )
|
| + if ( args[0] > 0 )
|
| {
|
| - /* check that there is enough room for new functions */
|
| - if ( CUR.numFDefs >= CUR.maxFDefs )
|
| + pCrec = exc->callStack + exc->callTop;
|
| +
|
| + pCrec->Caller_Range = exc->curRange;
|
| + pCrec->Caller_IP = exc->IP + 1;
|
| + pCrec->Cur_Count = (FT_Int)args[0];
|
| + pCrec->Def = def;
|
| +
|
| + exc->callTop++;
|
| +
|
| + Ins_Goto_CodeRange( exc, def->range, def->start );
|
| +
|
| + exc->step_ins = FALSE;
|
| + }
|
| +
|
| + return;
|
| +
|
| + Fail:
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + }
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* */
|
| + /* IDEF[]: Instruction DEFinition */
|
| + /* Opcode range: 0x89 */
|
| + /* Stack: Eint8 --> */
|
| + /* */
|
| + static void
|
| + Ins_IDEF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + TT_DefRecord* def;
|
| + TT_DefRecord* limit;
|
| +
|
| +
|
| + /* First of all, look for the same function in our table */
|
| +
|
| + def = exc->IDefs;
|
| + limit = def + exc->numIDefs;
|
| +
|
| + for ( ; def < limit; def++ )
|
| + if ( def->opc == (FT_ULong)args[0] )
|
| + break;
|
| +
|
| + if ( def == limit )
|
| + {
|
| + /* check that there is enough room for a new instruction */
|
| + if ( exc->numIDefs >= exc->maxIDefs )
|
| {
|
| - CUR.error = FT_THROW( Too_Many_Function_Defs );
|
| + exc->error = FT_THROW( Too_Many_Instruction_Defs );
|
| return;
|
| }
|
| - CUR.numFDefs++;
|
| + exc->numIDefs++;
|
| }
|
|
|
| - /* Although FDEF takes unsigned 32-bit integer, */
|
| - /* func # must be within unsigned 16-bit integer */
|
| - if ( n > 0xFFFFU )
|
| + /* opcode must be unsigned 8-bit integer */
|
| + if ( 0 > args[0] || args[0] > 0x00FF )
|
| {
|
| - CUR.error = FT_THROW( Too_Many_Function_Defs );
|
| + exc->error = FT_THROW( Too_Many_Instruction_Defs );
|
| return;
|
| }
|
|
|
| - rec->range = CUR.curRange;
|
| - rec->opc = (FT_UInt16)n;
|
| - rec->start = CUR.IP + 1;
|
| - rec->active = TRUE;
|
| - rec->inline_delta = FALSE;
|
| - rec->sph_fdef_flags = 0x0000;
|
| -
|
| - if ( n > CUR.maxFunc )
|
| - CUR.maxFunc = (FT_UInt16)n;
|
| + def->opc = (FT_Byte)args[0];
|
| + def->start = exc->IP + 1;
|
| + def->range = exc->curRange;
|
| + def->active = TRUE;
|
|
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - /* We don't know for sure these are typeman functions, */
|
| - /* however they are only active when RS 22 is called */
|
| - if ( n >= 64 && n <= 66 )
|
| - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
|
| -#endif
|
| + if ( (FT_ULong)args[0] > exc->maxIns )
|
| + exc->maxIns = (FT_Byte)args[0];
|
|
|
| /* Now skip the whole function definition. */
|
| - /* We don't allow nested IDEFS & FDEFs. */
|
| + /* We don't allow nested IDEFs & FDEFs. */
|
|
|
| - while ( SKIP_Code() == SUCCESS )
|
| + while ( SkipCode( exc ) == SUCCESS )
|
| {
|
| + switch ( exc->opcode )
|
| + {
|
| + case 0x89: /* IDEF */
|
| + case 0x2C: /* FDEF */
|
| + exc->error = FT_THROW( Nested_DEFS );
|
| + return;
|
| + case 0x2D: /* ENDF */
|
| + return;
|
| + }
|
| + }
|
| + }
|
|
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| - if ( SUBPIXEL_HINTING )
|
| - {
|
| - for ( i = 0; i < opcode_patterns; i++ )
|
| - {
|
| - if ( opcode_pointer[i] < opcode_size[i] &&
|
| - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
|
| - {
|
| - opcode_pointer[i] += 1;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* PUSHING DATA ONTO THE INTERPRETER STACK */
|
| + /* */
|
| + /*************************************************************************/
|
|
|
| - if ( opcode_pointer[i] == opcode_size[i] )
|
| - {
|
| - FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
|
| - i, n,
|
| - CUR.face->root.family_name,
|
| - CUR.face->root.style_name ));
|
|
|
| - switch ( i )
|
| - {
|
| - case 0:
|
| - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
|
| - break;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* NPUSHB[]: PUSH N Bytes */
|
| + /* Opcode range: 0x40 */
|
| + /* Stack: --> uint32... */
|
| + /* */
|
| + static void
|
| + Ins_NPUSHB( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + FT_UShort L, K;
|
|
|
| - case 1:
|
| - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
|
| - break;
|
|
|
| - case 2:
|
| - switch ( n )
|
| - {
|
| - /* needs to be implemented still */
|
| - case 58:
|
| - rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
|
| - }
|
| - break;
|
| + L = (FT_UShort)exc->code[exc->IP + 1];
|
|
|
| - case 3:
|
| - switch ( n )
|
| - {
|
| - case 0:
|
| - rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
|
| - }
|
| - break;
|
| + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
|
| + {
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| + }
|
|
|
| - case 4:
|
| - /* probably not necessary to detect anymore */
|
| - rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
|
| - break;
|
| + for ( K = 1; K <= L; K++ )
|
| + args[K - 1] = exc->code[exc->IP + K + 1];
|
|
|
| - case 5:
|
| - switch ( n )
|
| - {
|
| - case 0:
|
| - case 1:
|
| - case 2:
|
| - case 4:
|
| - case 7:
|
| - case 8:
|
| - rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
|
| - }
|
| - break;
|
| + exc->new_top += L;
|
| + }
|
|
|
| - case 6:
|
| - switch ( n )
|
| - {
|
| - case 0:
|
| - case 1:
|
| - case 2:
|
| - case 4:
|
| - case 7:
|
| - case 8:
|
| - rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
|
| - }
|
| - break;
|
|
|
| - case 7:
|
| - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| - break;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* NPUSHW[]: PUSH N Words */
|
| + /* Opcode range: 0x41 */
|
| + /* Stack: --> int32... */
|
| + /* */
|
| + static void
|
| + Ins_NPUSHW( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + FT_UShort L, K;
|
|
|
| - case 8:
|
| -#if 0
|
| - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
|
| -#endif
|
| - break;
|
| - }
|
| - opcode_pointer[i] = 0;
|
| - }
|
| - }
|
|
|
| - else
|
| - opcode_pointer[i] = 0;
|
| - }
|
| + L = (FT_UShort)exc->code[exc->IP + 1];
|
|
|
| - /* Set sph_compatibility_mode only when deltas are detected */
|
| - CUR.face->sph_compatibility_mode =
|
| - ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
|
| - ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
|
| - }
|
| + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
|
| + {
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| + }
|
|
|
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| + exc->IP += 2;
|
|
|
| - switch ( CUR.opcode )
|
| - {
|
| - case 0x89: /* IDEF */
|
| - case 0x2C: /* FDEF */
|
| - CUR.error = FT_THROW( Nested_DEFS );
|
| - return;
|
| + for ( K = 0; K < L; K++ )
|
| + args[K] = GetShortIns( exc );
|
|
|
| - case 0x2D: /* ENDF */
|
| - rec->end = CUR.IP;
|
| - return;
|
| - }
|
| + exc->step_ins = FALSE;
|
| + exc->new_top += L;
|
| + }
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* */
|
| + /* PUSHB[abc]: PUSH Bytes */
|
| + /* Opcode range: 0xB0-0xB7 */
|
| + /* Stack: --> uint32... */
|
| + /* */
|
| + static void
|
| + Ins_PUSHB( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + FT_UShort L, K;
|
| +
|
| +
|
| + L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
|
| +
|
| + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
|
| + {
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| }
|
| +
|
| + for ( K = 1; K <= L; K++ )
|
| + args[K - 1] = exc->code[exc->IP + K];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* ENDF[]: END Function definition */
|
| - /* Opcode range: 0x2D */
|
| - /* Stack: --> */
|
| + /* PUSHW[abc]: PUSH Words */
|
| + /* Opcode range: 0xB8-0xBF */
|
| + /* Stack: --> int32... */
|
| /* */
|
| static void
|
| - Ins_ENDF( INS_ARG )
|
| + Ins_PUSHW( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - TT_CallRec* pRec;
|
| + FT_UShort L, K;
|
| +
|
| +
|
| + L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
|
| +
|
| + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
|
| + {
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| + return;
|
| + }
|
| +
|
| + exc->IP++;
|
| +
|
| + for ( K = 0; K < L; K++ )
|
| + args[K] = GetShortIns( exc );
|
| +
|
| + exc->step_ins = FALSE;
|
| + }
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* */
|
| + /* MANAGING THE GRAPHICS STATE */
|
| + /* */
|
| + /*************************************************************************/
|
| +
|
|
|
| - FT_UNUSED_ARG;
|
| + static FT_Bool
|
| + Ins_SxVTL( TT_ExecContext exc,
|
| + FT_UShort aIdx1,
|
| + FT_UShort aIdx2,
|
| + FT_UnitVector* Vec )
|
| + {
|
| + FT_Long A, B, C;
|
| + FT_Vector* p1;
|
| + FT_Vector* p2;
|
|
|
| + FT_Byte opcode = exc->opcode;
|
|
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - CUR.sph_in_func_flags = 0x0000;
|
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */
|
| + if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
|
| + BOUNDS( aIdx2, exc->zp1.n_points ) )
|
| {
|
| - CUR.error = FT_THROW( ENDF_In_Exec_Stream );
|
| - return;
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + return FAILURE;
|
| }
|
|
|
| - CUR.callTop--;
|
| + p1 = exc->zp1.cur + aIdx2;
|
| + p2 = exc->zp2.cur + aIdx1;
|
|
|
| - pRec = &CUR.callStack[CUR.callTop];
|
| + A = p1->x - p2->x;
|
| + B = p1->y - p2->y;
|
|
|
| - pRec->Cur_Count--;
|
| + /* If p1 == p2, SPvTL and SFvTL behave the same as */
|
| + /* SPvTCA[X] and SFvTCA[X], respectively. */
|
| + /* */
|
| + /* Confirmed by Greg Hitchcock. */
|
|
|
| - CUR.step_ins = FALSE;
|
| + if ( A == 0 && B == 0 )
|
| + {
|
| + A = 0x4000;
|
| + opcode = 0;
|
| + }
|
|
|
| - if ( pRec->Cur_Count > 0 )
|
| + if ( ( opcode & 1 ) != 0 )
|
| {
|
| - CUR.callTop++;
|
| - CUR.IP = pRec->Def->start;
|
| + C = B; /* counter clockwise rotation */
|
| + B = A;
|
| + A = -C;
|
| }
|
| - else
|
| - /* Loop through the current function */
|
| - INS_Goto_CodeRange( pRec->Caller_Range,
|
| - pRec->Caller_IP );
|
|
|
| - /* Exit the current call frame. */
|
| + Normalize( A, B, Vec );
|
|
|
| - /* NOTE: If the last instruction of a program is a */
|
| - /* CALL or LOOPCALL, the return address is */
|
| - /* always out of the code range. This is a */
|
| - /* valid address, and it is why we do not test */
|
| - /* the result of Ins_Goto_CodeRange() here! */
|
| + return SUCCESS;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* CALL[]: CALL function */
|
| - /* Opcode range: 0x2B */
|
| - /* Stack: uint32? --> */
|
| + /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
|
| + /* Opcode range: 0x00-0x01 */
|
| + /* Stack: --> */
|
| + /* */
|
| + /* SPvTCA[a]: Set PVector to Coordinate Axis */
|
| + /* Opcode range: 0x02-0x03 */
|
| + /* Stack: --> */
|
| + /* */
|
| + /* SFvTCA[a]: Set FVector to Coordinate Axis */
|
| + /* Opcode range: 0x04-0x05 */
|
| + /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_CALL( INS_ARG )
|
| + Ins_SxyTCA( TT_ExecContext exc )
|
| {
|
| - FT_ULong F;
|
| - TT_CallRec* pCrec;
|
| - TT_DefRecord* def;
|
| -
|
| + FT_Short AA, BB;
|
|
|
| - /* first of all, check the index */
|
| + FT_Byte opcode = exc->opcode;
|
|
|
| - F = args[0];
|
| - if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
|
| - goto Fail;
|
|
|
| - /* Except for some old Apple fonts, all functions in a TrueType */
|
| - /* font are defined in increasing order, starting from 0. This */
|
| - /* means that we normally have */
|
| - /* */
|
| - /* CUR.maxFunc+1 == CUR.numFDefs */
|
| - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
|
| - /* */
|
| - /* If this isn't true, we need to look up the function table. */
|
| + AA = (FT_Short)( ( opcode & 1 ) << 14 );
|
| + BB = (FT_Short)( AA ^ 0x4000 );
|
|
|
| - def = CUR.FDefs + F;
|
| - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
|
| + if ( opcode < 4 )
|
| {
|
| - /* look up the FDefs table */
|
| - TT_DefRecord* limit;
|
| + exc->GS.projVector.x = AA;
|
| + exc->GS.projVector.y = BB;
|
|
|
| -
|
| - def = CUR.FDefs;
|
| - limit = def + CUR.numFDefs;
|
| -
|
| - while ( def < limit && def->opc != F )
|
| - def++;
|
| -
|
| - if ( def == limit )
|
| - goto Fail;
|
| + exc->GS.dualVector.x = AA;
|
| + exc->GS.dualVector.y = BB;
|
| }
|
| -
|
| - /* check that the function is active */
|
| - if ( !def->active )
|
| - goto Fail;
|
| -
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - ( ( CUR.iup_called &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
|
| - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
|
| - goto Fail;
|
| else
|
| - CUR.sph_in_func_flags = def->sph_fdef_flags;
|
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| + GUESS_VECTOR( projVector );
|
|
|
| - /* check the call stack */
|
| - if ( CUR.callTop >= CUR.callSize )
|
| + if ( ( opcode & 2 ) == 0 )
|
| {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| + exc->GS.freeVector.x = AA;
|
| + exc->GS.freeVector.y = BB;
|
| }
|
| + else
|
| + GUESS_VECTOR( freeVector );
|
|
|
| - pCrec = CUR.callStack + CUR.callTop;
|
| + Compute_Funcs( exc );
|
| + }
|
|
|
| - pCrec->Caller_Range = CUR.curRange;
|
| - pCrec->Caller_IP = CUR.IP + 1;
|
| - pCrec->Cur_Count = 1;
|
| - pCrec->Def = def;
|
|
|
| - CUR.callTop++;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SPvTL[a]: Set PVector To Line */
|
| + /* Opcode range: 0x06-0x07 */
|
| + /* Stack: uint32 uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SPVTL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + if ( Ins_SxVTL( exc,
|
| + (FT_UShort)args[1],
|
| + (FT_UShort)args[0],
|
| + &exc->GS.projVector ) == SUCCESS )
|
| + {
|
| + exc->GS.dualVector = exc->GS.projVector;
|
| + GUESS_VECTOR( freeVector );
|
| + Compute_Funcs( exc );
|
| + }
|
| + }
|
|
|
| - INS_Goto_CodeRange( def->range,
|
| - def->start );
|
|
|
| - CUR.step_ins = FALSE;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SFvTL[a]: Set FVector To Line */
|
| + /* Opcode range: 0x08-0x09 */
|
| + /* Stack: uint32 uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SFVTL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + if ( Ins_SxVTL( exc,
|
| + (FT_UShort)args[1],
|
| + (FT_UShort)args[0],
|
| + &exc->GS.freeVector ) == SUCCESS )
|
| + {
|
| + GUESS_VECTOR( projVector );
|
| + Compute_Funcs( exc );
|
| + }
|
| + }
|
|
|
| - return;
|
|
|
| - Fail:
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SFvTPv[]: Set FVector To PVector */
|
| + /* Opcode range: 0x0E */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_SFVTPV( TT_ExecContext exc )
|
| + {
|
| + GUESS_VECTOR( projVector );
|
| + exc->GS.freeVector = exc->GS.projVector;
|
| + Compute_Funcs( exc );
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* LOOPCALL[]: LOOP and CALL function */
|
| - /* Opcode range: 0x2A */
|
| - /* Stack: uint32? Eint16? --> */
|
| + /* SPvFS[]: Set PVector From Stack */
|
| + /* Opcode range: 0x0A */
|
| + /* Stack: f2.14 f2.14 --> */
|
| /* */
|
| static void
|
| - Ins_LOOPCALL( INS_ARG )
|
| + Ins_SPVFS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - FT_ULong F;
|
| - TT_CallRec* pCrec;
|
| - TT_DefRecord* def;
|
| + FT_Short S;
|
| + FT_Long X, Y;
|
|
|
|
|
| - /* first of all, check the index */
|
| - F = args[1];
|
| - if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
|
| - goto Fail;
|
| + /* Only use low 16bits, then sign extend */
|
| + S = (FT_Short)args[1];
|
| + Y = (FT_Long)S;
|
| + S = (FT_Short)args[0];
|
| + X = (FT_Long)S;
|
|
|
| - /* Except for some old Apple fonts, all functions in a TrueType */
|
| - /* font are defined in increasing order, starting from 0. This */
|
| - /* means that we normally have */
|
| - /* */
|
| - /* CUR.maxFunc+1 == CUR.numFDefs */
|
| - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
|
| - /* */
|
| - /* If this isn't true, we need to look up the function table. */
|
| + Normalize( X, Y, &exc->GS.projVector );
|
|
|
| - def = CUR.FDefs + F;
|
| - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
|
| - {
|
| - /* look up the FDefs table */
|
| - TT_DefRecord* limit;
|
| + exc->GS.dualVector = exc->GS.projVector;
|
| + GUESS_VECTOR( freeVector );
|
| + Compute_Funcs( exc );
|
| + }
|
|
|
|
|
| - def = CUR.FDefs;
|
| - limit = def + CUR.numFDefs;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SFvFS[]: Set FVector From Stack */
|
| + /* Opcode range: 0x0B */
|
| + /* Stack: f2.14 f2.14 --> */
|
| + /* */
|
| + static void
|
| + Ins_SFVFS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + FT_Short S;
|
| + FT_Long X, Y;
|
|
|
| - while ( def < limit && def->opc != F )
|
| - def++;
|
|
|
| - if ( def == limit )
|
| - goto Fail;
|
| - }
|
| + /* Only use low 16bits, then sign extend */
|
| + S = (FT_Short)args[1];
|
| + Y = (FT_Long)S;
|
| + S = (FT_Short)args[0];
|
| + X = S;
|
|
|
| - /* check that the function is active */
|
| - if ( !def->active )
|
| - goto Fail;
|
| + Normalize( X, Y, &exc->GS.freeVector );
|
| + GUESS_VECTOR( projVector );
|
| + Compute_Funcs( exc );
|
| + }
|
|
|
| -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
|
| - goto Fail;
|
| - else
|
| - CUR.sph_in_func_flags = def->sph_fdef_flags;
|
| -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - /* check stack */
|
| - if ( CUR.callTop >= CUR.callSize )
|
| + /*************************************************************************/
|
| + /* */
|
| + /* GPv[]: Get Projection Vector */
|
| + /* Opcode range: 0x0C */
|
| + /* Stack: ef2.14 --> ef2.14 */
|
| + /* */
|
| + static void
|
| + Ins_GPV( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| + args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
|
| + args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
|
| }
|
| -
|
| - if ( args[0] > 0 )
|
| + else
|
| {
|
| - pCrec = CUR.callStack + CUR.callTop;
|
| -
|
| - pCrec->Caller_Range = CUR.curRange;
|
| - pCrec->Caller_IP = CUR.IP + 1;
|
| - pCrec->Cur_Count = (FT_Int)args[0];
|
| - pCrec->Def = def;
|
| -
|
| - CUR.callTop++;
|
| -
|
| - INS_Goto_CodeRange( def->range, def->start );
|
| -
|
| - CUR.step_ins = FALSE;
|
| + args[0] = exc->GS.projVector.x;
|
| + args[1] = exc->GS.projVector.y;
|
| }
|
| -
|
| - return;
|
| -
|
| - Fail:
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| +#else
|
| + args[0] = exc->GS.projVector.x;
|
| + args[1] = exc->GS.projVector.y;
|
| +#endif
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* IDEF[]: Instruction DEFinition */
|
| - /* Opcode range: 0x89 */
|
| - /* Stack: Eint8 --> */
|
| + /* GFv[]: Get Freedom Vector */
|
| + /* Opcode range: 0x0D */
|
| + /* Stack: ef2.14 --> ef2.14 */
|
| /* */
|
| static void
|
| - Ins_IDEF( INS_ARG )
|
| + Ins_GFV( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - TT_DefRecord* def;
|
| - TT_DefRecord* limit;
|
| -
|
| -
|
| - /* First of all, look for the same function in our table */
|
| -
|
| - def = CUR.IDefs;
|
| - limit = def + CUR.numIDefs;
|
| -
|
| - for ( ; def < limit; def++ )
|
| - if ( def->opc == (FT_ULong)args[0] )
|
| - break;
|
| -
|
| - if ( def == limit )
|
| +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - /* check that there is enough room for a new instruction */
|
| - if ( CUR.numIDefs >= CUR.maxIDefs )
|
| - {
|
| - CUR.error = FT_THROW( Too_Many_Instruction_Defs );
|
| - return;
|
| - }
|
| - CUR.numIDefs++;
|
| + args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
|
| + args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
|
| }
|
| -
|
| - /* opcode must be unsigned 8-bit integer */
|
| - if ( 0 > args[0] || args[0] > 0x00FF )
|
| + else
|
| {
|
| - CUR.error = FT_THROW( Too_Many_Instruction_Defs );
|
| - return;
|
| + args[0] = exc->GS.freeVector.x;
|
| + args[1] = exc->GS.freeVector.y;
|
| }
|
| +#else
|
| + args[0] = exc->GS.freeVector.x;
|
| + args[1] = exc->GS.freeVector.y;
|
| +#endif
|
| + }
|
|
|
| - def->opc = (FT_Byte)args[0];
|
| - def->start = CUR.IP + 1;
|
| - def->range = CUR.curRange;
|
| - def->active = TRUE;
|
|
|
| - if ( (FT_ULong)args[0] > CUR.maxIns )
|
| - CUR.maxIns = (FT_Byte)args[0];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SRP0[]: Set Reference Point 0 */
|
| + /* Opcode range: 0x10 */
|
| + /* Stack: uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SRP0( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.rp0 = (FT_UShort)args[0];
|
| + }
|
|
|
| - /* Now skip the whole function definition. */
|
| - /* We don't allow nested IDEFs & FDEFs. */
|
|
|
| - while ( SKIP_Code() == SUCCESS )
|
| - {
|
| - switch ( CUR.opcode )
|
| - {
|
| - case 0x89: /* IDEF */
|
| - case 0x2C: /* FDEF */
|
| - CUR.error = FT_THROW( Nested_DEFS );
|
| - return;
|
| - case 0x2D: /* ENDF */
|
| - return;
|
| - }
|
| - }
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SRP1[]: Set Reference Point 1 */
|
| + /* Opcode range: 0x11 */
|
| + /* Stack: uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SRP1( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.rp1 = (FT_UShort)args[0];
|
| + }
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SRP2[]: Set Reference Point 2 */
|
| + /* Opcode range: 0x12 */
|
| + /* Stack: uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SRP2( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.rp2 = (FT_UShort)args[0];
|
| + }
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SMD[]: Set Minimum Distance */
|
| + /* Opcode range: 0x1A */
|
| + /* Stack: f26.6 --> */
|
| + /* */
|
| + static void
|
| + Ins_SMD( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.minimum_distance = args[0];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* PUSHING DATA ONTO THE INTERPRETER STACK */
|
| - /* */
|
| - /* Instructions appear in the specification's order. */
|
| + /* SCVTCI[]: Set Control Value Table Cut In */
|
| + /* Opcode range: 0x1D */
|
| + /* Stack: f26.6 --> */
|
| /* */
|
| - /*************************************************************************/
|
| + static void
|
| + Ins_SCVTCI( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
|
| + }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* NPUSHB[]: PUSH N Bytes */
|
| - /* Opcode range: 0x40 */
|
| - /* Stack: --> uint32... */
|
| + /* SSWCI[]: Set Single Width Cut In */
|
| + /* Opcode range: 0x1E */
|
| + /* Stack: f26.6 --> */
|
| /* */
|
| static void
|
| - Ins_NPUSHB( INS_ARG )
|
| + Ins_SSWCI( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - FT_UShort L, K;
|
| + exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
|
| + }
|
|
|
|
|
| - L = (FT_UShort)CUR.code[CUR.IP + 1];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SSW[]: Set Single Width */
|
| + /* Opcode range: 0x1F */
|
| + /* Stack: int32? --> */
|
| + /* */
|
| + static void
|
| + Ins_SSW( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.single_width_value = FT_MulFix( args[0],
|
| + exc->tt_metrics.scale );
|
| + }
|
|
|
| - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
|
| - {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| - }
|
|
|
| - for ( K = 1; K <= L; K++ )
|
| - args[K - 1] = CUR.code[CUR.IP + K + 1];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* FLIPON[]: Set auto-FLIP to ON */
|
| + /* Opcode range: 0x4D */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_FLIPON( TT_ExecContext exc )
|
| + {
|
| + exc->GS.auto_flip = TRUE;
|
| + }
|
| +
|
|
|
| - CUR.new_top += L;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* FLIPOFF[]: Set auto-FLIP to OFF */
|
| + /* Opcode range: 0x4E */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_FLIPOFF( TT_ExecContext exc )
|
| + {
|
| + exc->GS.auto_flip = FALSE;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* NPUSHW[]: PUSH N Words */
|
| - /* Opcode range: 0x41 */
|
| - /* Stack: --> int32... */
|
| + /* SANGW[]: Set ANGle Weight */
|
| + /* Opcode range: 0x7E */
|
| + /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_NPUSHW( INS_ARG )
|
| + Ins_SANGW( void )
|
| {
|
| - FT_UShort L, K;
|
| + /* instruction not supported anymore */
|
| + }
|
|
|
|
|
| - L = (FT_UShort)CUR.code[CUR.IP + 1];
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SDB[]: Set Delta Base */
|
| + /* Opcode range: 0x5E */
|
| + /* Stack: uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SDB( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + exc->GS.delta_base = (FT_UShort)args[0];
|
| + }
|
|
|
| - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
|
| - {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| - }
|
|
|
| - CUR.IP += 2;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SDS[]: Set Delta Shift */
|
| + /* Opcode range: 0x5F */
|
| + /* Stack: uint32 --> */
|
| + /* */
|
| + static void
|
| + Ins_SDS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + if ( (FT_ULong)args[0] > 6UL )
|
| + exc->error = FT_THROW( Bad_Argument );
|
| + else
|
| + exc->GS.delta_shift = (FT_UShort)args[0];
|
| + }
|
|
|
| - for ( K = 0; K < L; K++ )
|
| - args[K] = GET_ShortIns();
|
|
|
| - CUR.step_ins = FALSE;
|
| - CUR.new_top += L;
|
| + /*************************************************************************/
|
| + /* */
|
| + /* RTHG[]: Round To Half Grid */
|
| + /* Opcode range: 0x19 */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_RTHG( TT_ExecContext exc )
|
| + {
|
| + exc->GS.round_state = TT_Round_To_Half_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* PUSHB[abc]: PUSH Bytes */
|
| - /* Opcode range: 0xB0-0xB7 */
|
| - /* Stack: --> uint32... */
|
| + /* RTG[]: Round To Grid */
|
| + /* Opcode range: 0x18 */
|
| + /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_PUSHB( INS_ARG )
|
| + Ins_RTG( TT_ExecContext exc )
|
| {
|
| - FT_UShort L, K;
|
| + exc->GS.round_state = TT_Round_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Grid;
|
| + }
|
|
|
|
|
| - L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );
|
| + /*************************************************************************/
|
| + /* RTDG[]: Round To Double Grid */
|
| + /* Opcode range: 0x3D */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_RTDG( TT_ExecContext exc )
|
| + {
|
| + exc->GS.round_state = TT_Round_To_Double_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
|
| + }
|
|
|
| - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
|
| - {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| - }
|
|
|
| - for ( K = 1; K <= L; K++ )
|
| - args[K - 1] = CUR.code[CUR.IP + K];
|
| + /*************************************************************************/
|
| + /* RUTG[]: Round Up To Grid */
|
| + /* Opcode range: 0x7C */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_RUTG( TT_ExecContext exc )
|
| + {
|
| + exc->GS.round_state = TT_Round_Up_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* PUSHW[abc]: PUSH Words */
|
| - /* Opcode range: 0xB8-0xBF */
|
| - /* Stack: --> int32... */
|
| + /* RDTG[]: Round Down To Grid */
|
| + /* Opcode range: 0x7D */
|
| + /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_PUSHW( INS_ARG )
|
| + Ins_RDTG( TT_ExecContext exc )
|
| {
|
| - FT_UShort L, K;
|
| -
|
| + exc->GS.round_state = TT_Round_Down_To_Grid;
|
| + exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
|
| + }
|
|
|
| - L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );
|
|
|
| - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
|
| - {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| - return;
|
| - }
|
| + /*************************************************************************/
|
| + /* */
|
| + /* ROFF[]: Round OFF */
|
| + /* Opcode range: 0x7A */
|
| + /* Stack: --> */
|
| + /* */
|
| + static void
|
| + Ins_ROFF( TT_ExecContext exc )
|
| + {
|
| + exc->GS.round_state = TT_Round_Off;
|
| + exc->func_round = (TT_Round_Func)Round_None;
|
| + }
|
|
|
| - CUR.IP++;
|
|
|
| - for ( K = 0; K < L; K++ )
|
| - args[K] = GET_ShortIns();
|
| + /*************************************************************************/
|
| + /* */
|
| + /* SROUND[]: Super ROUND */
|
| + /* Opcode range: 0x76 */
|
| + /* Stack: Eint8 --> */
|
| + /* */
|
| + static void
|
| + Ins_SROUND( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + SetSuperRound( exc, 0x4000, args[0] );
|
|
|
| - CUR.step_ins = FALSE;
|
| + exc->GS.round_state = TT_Round_Super;
|
| + exc->func_round = (TT_Round_Func)Round_Super;
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* MANAGING THE GRAPHICS STATE */
|
| - /* */
|
| - /* Instructions appear in the specs' order. */
|
| + /* S45ROUND[]: Super ROUND 45 degrees */
|
| + /* Opcode range: 0x77 */
|
| + /* Stack: uint32 --> */
|
| /* */
|
| - /*************************************************************************/
|
| + static void
|
| + Ins_S45ROUND( TT_ExecContext exc,
|
| + FT_Long* args )
|
| + {
|
| + SetSuperRound( exc, 0x2D41, args[0] );
|
| +
|
| + exc->GS.round_state = TT_Round_Super_45;
|
| + exc->func_round = (TT_Round_Func)Round_Super_45;
|
| + }
|
|
|
|
|
| /*************************************************************************/
|
| @@ -5269,7 +4776,8 @@
|
| /* along the dual projection vector! */
|
| /* */
|
| static void
|
| - Ins_GC( INS_ARG )
|
| + Ins_GC( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_ULong L;
|
| FT_F26Dot6 R;
|
| @@ -5277,18 +4785,18 @@
|
|
|
| L = (FT_ULong)args[0];
|
|
|
| - if ( BOUNDSL( L, CUR.zp2.n_points ) )
|
| + if ( BOUNDSL( L, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| R = 0;
|
| }
|
| else
|
| {
|
| - if ( CUR.opcode & 1 )
|
| - R = CUR_fast_dualproj( &CUR.zp2.org[L] );
|
| + if ( exc->opcode & 1 )
|
| + R = FAST_DUALPROJ( &exc->zp2.org[L] );
|
| else
|
| - R = CUR_fast_project( &CUR.zp2.cur[L] );
|
| + R = FAST_PROJECT( &exc->zp2.cur[L] );
|
| }
|
|
|
| args[0] = R;
|
| @@ -5306,7 +4814,8 @@
|
| /* OA := OA + ( value - OA.p )/( f.p ) * f */
|
| /* */
|
| static void
|
| - Ins_SCFS( INS_ARG )
|
| + Ins_SCFS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_Long K;
|
| FT_UShort L;
|
| @@ -5314,21 +4823,21 @@
|
|
|
| L = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( L, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( L, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - K = CUR_fast_project( &CUR.zp2.cur[L] );
|
| + K = FAST_PROJECT( &exc->zp2.cur[L] );
|
|
|
| - CUR_Func_move( &CUR.zp2, L, args[1] - K );
|
| + exc->func_move( exc, &exc->zp2, L, args[1] - K );
|
|
|
| /* UNDOCUMENTED! The MS rasterizer does that with */
|
| /* twilight points (confirmed by Greg Hitchcock) */
|
| - if ( CUR.GS.gep2 == 0 )
|
| - CUR.zp2.org[L] = CUR.zp2.cur[L];
|
| + if ( exc->GS.gep2 == 0 )
|
| + exc->zp2.org[L] = exc->zp2.cur[L];
|
| }
|
|
|
|
|
| @@ -5348,7 +4857,8 @@
|
| /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */
|
| /* */
|
| static void
|
| - Ins_MD( INS_ARG )
|
| + Ins_MD( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort K, L;
|
| FT_F26Dot6 D;
|
| @@ -5357,50 +4867,50 @@
|
| K = (FT_UShort)args[1];
|
| L = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( L, CUR.zp0.n_points ) ||
|
| - BOUNDS( K, CUR.zp1.n_points ) )
|
| + if ( BOUNDS( L, exc->zp0.n_points ) ||
|
| + BOUNDS( K, exc->zp1.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| D = 0;
|
| }
|
| else
|
| {
|
| - if ( CUR.opcode & 1 )
|
| - D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
|
| + if ( exc->opcode & 1 )
|
| + D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
|
| else
|
| {
|
| /* XXX: UNDOCUMENTED: twilight zone special case */
|
|
|
| - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
|
| + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
|
| {
|
| - FT_Vector* vec1 = CUR.zp0.org + L;
|
| - FT_Vector* vec2 = CUR.zp1.org + K;
|
| + FT_Vector* vec1 = exc->zp0.org + L;
|
| + FT_Vector* vec2 = exc->zp1.org + K;
|
|
|
|
|
| - D = CUR_Func_dualproj( vec1, vec2 );
|
| + D = DUALPROJ( vec1, vec2 );
|
| }
|
| else
|
| {
|
| - FT_Vector* vec1 = CUR.zp0.orus + L;
|
| - FT_Vector* vec2 = CUR.zp1.orus + K;
|
| + FT_Vector* vec1 = exc->zp0.orus + L;
|
| + FT_Vector* vec2 = exc->zp1.orus + K;
|
|
|
|
|
| - if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
|
| + if ( exc->metrics.x_scale == exc->metrics.y_scale )
|
| {
|
| /* this should be faster */
|
| - D = CUR_Func_dualproj( vec1, vec2 );
|
| - D = FT_MulFix( D, CUR.metrics.x_scale );
|
| + D = DUALPROJ( vec1, vec2 );
|
| + D = FT_MulFix( D, exc->metrics.x_scale );
|
| }
|
| else
|
| {
|
| FT_Vector vec;
|
|
|
|
|
| - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
|
| - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
|
| + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
|
| + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
|
|
|
| - D = CUR_fast_dualproj( &vec );
|
| + D = FAST_DUALPROJ( &vec );
|
| }
|
| }
|
| }
|
| @@ -5408,8 +4918,9 @@
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode && FT_ABS( D ) == 64 )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + FT_ABS( D ) == 64 )
|
| D += 1;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| @@ -5419,61 +4930,63 @@
|
|
|
| /*************************************************************************/
|
| /* */
|
| - /* SDPVTL[a]: Set Dual PVector to Line */
|
| + /* SDPvTL[a]: Set Dual PVector to Line */
|
| /* Opcode range: 0x86-0x87 */
|
| /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SDPVTL( INS_ARG )
|
| + Ins_SDPVTL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_Long A, B, C;
|
| FT_UShort p1, p2; /* was FT_Int in pas type ERROR */
|
| - FT_Int aOpc = CUR.opcode;
|
| +
|
| + FT_Byte opcode = exc->opcode;
|
|
|
|
|
| p1 = (FT_UShort)args[1];
|
| p2 = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( p2, CUR.zp1.n_points ) ||
|
| - BOUNDS( p1, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( p2, exc->zp1.n_points ) ||
|
| + BOUNDS( p1, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| {
|
| - FT_Vector* v1 = CUR.zp1.org + p2;
|
| - FT_Vector* v2 = CUR.zp2.org + p1;
|
| + FT_Vector* v1 = exc->zp1.org + p2;
|
| + FT_Vector* v2 = exc->zp2.org + p1;
|
|
|
|
|
| A = v1->x - v2->x;
|
| B = v1->y - v2->y;
|
|
|
| - /* If v1 == v2, SDPVTL behaves the same as */
|
| + /* If v1 == v2, SDPvTL behaves the same as */
|
| /* SVTCA[X], respectively. */
|
| /* */
|
| /* Confirmed by Greg Hitchcock. */
|
|
|
| if ( A == 0 && B == 0 )
|
| {
|
| - A = 0x4000;
|
| - aOpc = 0;
|
| + A = 0x4000;
|
| + opcode = 0;
|
| }
|
| }
|
|
|
| - if ( ( aOpc & 1 ) != 0 )
|
| + if ( ( opcode & 1 ) != 0 )
|
| {
|
| C = B; /* counter clockwise rotation */
|
| B = A;
|
| A = -C;
|
| }
|
|
|
| - NORMalize( A, B, &CUR.GS.dualVector );
|
| + Normalize( A, B, &exc->GS.dualVector );
|
|
|
| {
|
| - FT_Vector* v1 = CUR.zp1.cur + p2;
|
| - FT_Vector* v2 = CUR.zp2.cur + p1;
|
| + FT_Vector* v1 = exc->zp1.cur + p2;
|
| + FT_Vector* v2 = exc->zp2.cur + p1;
|
|
|
|
|
| A = v1->x - v2->x;
|
| @@ -5481,23 +4994,21 @@
|
|
|
| if ( A == 0 && B == 0 )
|
| {
|
| - A = 0x4000;
|
| - aOpc = 0;
|
| + A = 0x4000;
|
| + opcode = 0;
|
| }
|
| }
|
|
|
| - if ( ( aOpc & 1 ) != 0 )
|
| + if ( ( opcode & 1 ) != 0 )
|
| {
|
| C = B; /* counter clockwise rotation */
|
| B = A;
|
| A = -C;
|
| }
|
|
|
| - NORMalize( A, B, &CUR.GS.projVector );
|
| -
|
| + Normalize( A, B, &exc->GS.projVector );
|
| GUESS_VECTOR( freeVector );
|
| -
|
| - COMPUTE_Funcs();
|
| + Compute_Funcs( exc );
|
| }
|
|
|
|
|
| @@ -5508,25 +5019,26 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SZP0( INS_ARG )
|
| + Ins_SZP0( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| switch ( (FT_Int)args[0] )
|
| {
|
| case 0:
|
| - CUR.zp0 = CUR.twilight;
|
| + exc->zp0 = exc->twilight;
|
| break;
|
|
|
| case 1:
|
| - CUR.zp0 = CUR.pts;
|
| + exc->zp0 = exc->pts;
|
| break;
|
|
|
| default:
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - CUR.GS.gep0 = (FT_UShort)args[0];
|
| + exc->GS.gep0 = (FT_UShort)args[0];
|
| }
|
|
|
|
|
| @@ -5537,25 +5049,26 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SZP1( INS_ARG )
|
| + Ins_SZP1( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| switch ( (FT_Int)args[0] )
|
| {
|
| case 0:
|
| - CUR.zp1 = CUR.twilight;
|
| + exc->zp1 = exc->twilight;
|
| break;
|
|
|
| case 1:
|
| - CUR.zp1 = CUR.pts;
|
| + exc->zp1 = exc->pts;
|
| break;
|
|
|
| default:
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - CUR.GS.gep1 = (FT_UShort)args[0];
|
| + exc->GS.gep1 = (FT_UShort)args[0];
|
| }
|
|
|
|
|
| @@ -5566,25 +5079,26 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SZP2( INS_ARG )
|
| + Ins_SZP2( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| switch ( (FT_Int)args[0] )
|
| {
|
| case 0:
|
| - CUR.zp2 = CUR.twilight;
|
| + exc->zp2 = exc->twilight;
|
| break;
|
|
|
| case 1:
|
| - CUR.zp2 = CUR.pts;
|
| + exc->zp2 = exc->pts;
|
| break;
|
|
|
| default:
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - CUR.GS.gep2 = (FT_UShort)args[0];
|
| + exc->GS.gep2 = (FT_UShort)args[0];
|
| }
|
|
|
|
|
| @@ -5595,60 +5109,82 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SZPS( INS_ARG )
|
| + Ins_SZPS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| switch ( (FT_Int)args[0] )
|
| {
|
| case 0:
|
| - CUR.zp0 = CUR.twilight;
|
| + exc->zp0 = exc->twilight;
|
| break;
|
|
|
| case 1:
|
| - CUR.zp0 = CUR.pts;
|
| + exc->zp0 = exc->pts;
|
| break;
|
|
|
| default:
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - CUR.zp1 = CUR.zp0;
|
| - CUR.zp2 = CUR.zp0;
|
| + exc->zp1 = exc->zp0;
|
| + exc->zp2 = exc->zp0;
|
|
|
| - CUR.GS.gep0 = (FT_UShort)args[0];
|
| - CUR.GS.gep1 = (FT_UShort)args[0];
|
| - CUR.GS.gep2 = (FT_UShort)args[0];
|
| + exc->GS.gep0 = (FT_UShort)args[0];
|
| + exc->GS.gep1 = (FT_UShort)args[0];
|
| + exc->GS.gep2 = (FT_UShort)args[0];
|
| }
|
|
|
|
|
| /*************************************************************************/
|
| /* */
|
| /* INSTCTRL[]: INSTruction ConTRoL */
|
| - /* Opcode range: 0x8e */
|
| + /* Opcode range: 0x8E */
|
| /* Stack: int32 int32 --> */
|
| /* */
|
| static void
|
| - Ins_INSTCTRL( INS_ARG )
|
| + Ins_INSTCTRL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| - FT_Long K, L;
|
| + FT_ULong K, L, Kf;
|
|
|
|
|
| - K = args[1];
|
| - L = args[0];
|
| + K = (FT_ULong)args[1];
|
| + L = (FT_ULong)args[0];
|
|
|
| - if ( K < 1 || K > 2 )
|
| + /* selector values cannot be `OR'ed; */
|
| + /* they are indices starting with index 1, not flags */
|
| + if ( K < 1 || K > 3 )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| + /* convert index to flag value */
|
| + Kf = 1 << ( K - 1 );
|
| +
|
| if ( L != 0 )
|
| - L = K;
|
| + {
|
| + /* arguments to selectors look like flag values */
|
| + if ( L != Kf )
|
| + {
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| + return;
|
| + }
|
| + }
|
|
|
| - CUR.GS.instruct_control = FT_BOOL(
|
| - ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
|
| + exc->GS.instruct_control &= ~(FT_Byte)Kf;
|
| + exc->GS.instruct_control |= (FT_Byte)L;
|
| +
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| + /* INSTCTRL modifying flag 3 also has an effect */
|
| + /* outside of the CVT program */
|
| + if ( K == 3 )
|
| + exc->ignore_x_mode = FT_BOOL( L == 4 );
|
| +#endif
|
| }
|
|
|
|
|
| @@ -5659,7 +5195,8 @@
|
| /* Stack: uint32? --> */
|
| /* */
|
| static void
|
| - Ins_SCANCTRL( INS_ARG )
|
| + Ins_SCANCTRL( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_Int A;
|
|
|
| @@ -5669,32 +5206,32 @@
|
|
|
| if ( A == 0xFF )
|
| {
|
| - CUR.GS.scan_control = TRUE;
|
| + exc->GS.scan_control = TRUE;
|
| return;
|
| }
|
| else if ( A == 0 )
|
| {
|
| - CUR.GS.scan_control = FALSE;
|
| + exc->GS.scan_control = FALSE;
|
| return;
|
| }
|
|
|
| - if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
|
| - CUR.GS.scan_control = TRUE;
|
| + if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
|
| + exc->GS.scan_control = TRUE;
|
|
|
| - if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
|
| - CUR.GS.scan_control = TRUE;
|
| + if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
|
| + exc->GS.scan_control = TRUE;
|
|
|
| - if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
|
| - CUR.GS.scan_control = TRUE;
|
| + if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
|
| + exc->GS.scan_control = TRUE;
|
|
|
| - if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
|
| - CUR.GS.scan_control = FALSE;
|
| + if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
|
| + exc->GS.scan_control = FALSE;
|
|
|
| - if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
|
| - CUR.GS.scan_control = FALSE;
|
| + if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
|
| + exc->GS.scan_control = FALSE;
|
|
|
| - if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
|
| - CUR.GS.scan_control = FALSE;
|
| + if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
|
| + exc->GS.scan_control = FALSE;
|
| }
|
|
|
|
|
| @@ -5705,10 +5242,11 @@
|
| /* Stack: uint32? --> */
|
| /* */
|
| static void
|
| - Ins_SCANTYPE( INS_ARG )
|
| + Ins_SCANTYPE( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| if ( args[0] >= 0 )
|
| - CUR.GS.scan_type = (FT_Int)args[0];
|
| + exc->GS.scan_type = (FT_Int)args[0];
|
| }
|
|
|
|
|
| @@ -5716,8 +5254,6 @@
|
| /* */
|
| /* MANAGING OUTLINES */
|
| /* */
|
| - /* Instructions appear in the specification's order. */
|
| - /* */
|
| /*************************************************************************/
|
|
|
|
|
| @@ -5728,43 +5264,41 @@
|
| /* Stack: uint32... --> */
|
| /* */
|
| static void
|
| - Ins_FLIPPT( INS_ARG )
|
| + Ins_FLIPPT( TT_ExecContext exc )
|
| {
|
| FT_UShort point;
|
|
|
| - FT_UNUSED_ARG;
|
|
|
| -
|
| - if ( CUR.top < CUR.GS.loop )
|
| + if ( exc->top < exc->GS.loop )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| goto Fail;
|
| }
|
|
|
| - while ( CUR.GS.loop > 0 )
|
| + while ( exc->GS.loop > 0 )
|
| {
|
| - CUR.args--;
|
| + exc->args--;
|
|
|
| - point = (FT_UShort)CUR.stack[CUR.args];
|
| + point = (FT_UShort)exc->stack[exc->args];
|
|
|
| - if ( BOUNDS( point, CUR.pts.n_points ) )
|
| + if ( BOUNDS( point, exc->pts.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| }
|
| else
|
| - CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;
|
| + exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
|
|
|
| - CUR.GS.loop--;
|
| + exc->GS.loop--;
|
| }
|
|
|
| Fail:
|
| - CUR.GS.loop = 1;
|
| - CUR.new_top = CUR.args;
|
| + exc->GS.loop = 1;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -5775,7 +5309,8 @@
|
| /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_FLIPRGON( INS_ARG )
|
| + Ins_FLIPRGON( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort I, K, L;
|
|
|
| @@ -5783,16 +5318,16 @@
|
| K = (FT_UShort)args[1];
|
| L = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( K, CUR.pts.n_points ) ||
|
| - BOUNDS( L, CUR.pts.n_points ) )
|
| + if ( BOUNDS( K, exc->pts.n_points ) ||
|
| + BOUNDS( L, exc->pts.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| for ( I = L; I <= K; I++ )
|
| - CUR.pts.tags[I] |= FT_CURVE_TAG_ON;
|
| + exc->pts.tags[I] |= FT_CURVE_TAG_ON;
|
| }
|
|
|
|
|
| @@ -5803,7 +5338,8 @@
|
| /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_FLIPRGOFF( INS_ARG )
|
| + Ins_FLIPRGOFF( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort I, K, L;
|
|
|
| @@ -5811,45 +5347,46 @@
|
| K = (FT_UShort)args[1];
|
| L = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( K, CUR.pts.n_points ) ||
|
| - BOUNDS( L, CUR.pts.n_points ) )
|
| + if ( BOUNDS( K, exc->pts.n_points ) ||
|
| + BOUNDS( L, exc->pts.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| for ( I = L; I <= K; I++ )
|
| - CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;
|
| + exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
|
| }
|
|
|
|
|
| static FT_Bool
|
| - Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x,
|
| - FT_F26Dot6* y,
|
| - TT_GlyphZone zone,
|
| - FT_UShort* refp )
|
| + Compute_Point_Displacement( TT_ExecContext exc,
|
| + FT_F26Dot6* x,
|
| + FT_F26Dot6* y,
|
| + TT_GlyphZone zone,
|
| + FT_UShort* refp )
|
| {
|
| TT_GlyphZoneRec zp;
|
| FT_UShort p;
|
| FT_F26Dot6 d;
|
|
|
|
|
| - if ( CUR.opcode & 1 )
|
| + if ( exc->opcode & 1 )
|
| {
|
| - zp = CUR.zp0;
|
| - p = CUR.GS.rp1;
|
| + zp = exc->zp0;
|
| + p = exc->GS.rp1;
|
| }
|
| else
|
| {
|
| - zp = CUR.zp1;
|
| - p = CUR.GS.rp2;
|
| + zp = exc->zp1;
|
| + p = exc->GS.rp2;
|
| }
|
|
|
| if ( BOUNDS( p, zp.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| *refp = 0;
|
| return FAILURE;
|
| }
|
| @@ -5857,12 +5394,12 @@
|
| *zone = zp;
|
| *refp = p;
|
|
|
| - d = CUR_Func_project( zp.cur + p, zp.org + p );
|
| + d = PROJECT( zp.cur + p, zp.org + p );
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - if ( CUR.GS.both_x_axis )
|
| + if ( exc->GS.both_x_axis )
|
| {
|
| *x = d;
|
| *y = 0;
|
| @@ -5876,8 +5413,8 @@
|
| else
|
| #endif
|
| {
|
| - *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
|
| - *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
|
| + *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
|
| + *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
|
| }
|
|
|
| return SUCCESS;
|
| @@ -5885,42 +5422,43 @@
|
|
|
|
|
| static void
|
| - Move_Zp2_Point( EXEC_OP_ FT_UShort point,
|
| - FT_F26Dot6 dx,
|
| - FT_F26Dot6 dy,
|
| - FT_Bool touch )
|
| + Move_Zp2_Point( TT_ExecContext exc,
|
| + FT_UShort point,
|
| + FT_F26Dot6 dx,
|
| + FT_F26Dot6 dy,
|
| + FT_Bool touch )
|
| {
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - if ( CUR.GS.both_x_axis )
|
| + if ( exc->GS.both_x_axis )
|
| {
|
| - CUR.zp2.cur[point].x += dx;
|
| + exc->zp2.cur[point].x += dx;
|
| if ( touch )
|
| - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
| + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
| }
|
| else
|
| {
|
| - CUR.zp2.cur[point].y += dy;
|
| + exc->zp2.cur[point].y += dy;
|
| if ( touch )
|
| - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| }
|
| return;
|
| }
|
| #endif
|
|
|
| - if ( CUR.GS.freeVector.x != 0 )
|
| + if ( exc->GS.freeVector.x != 0 )
|
| {
|
| - CUR.zp2.cur[point].x += dx;
|
| + exc->zp2.cur[point].x += dx;
|
| if ( touch )
|
| - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
| + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
| }
|
|
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| + if ( exc->GS.freeVector.y != 0 )
|
| {
|
| - CUR.zp2.cur[point].y += dy;
|
| + exc->zp2.cur[point].y += dy;
|
| if ( touch )
|
| - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
| }
|
| }
|
|
|
| @@ -5932,57 +5470,54 @@
|
| /* Stack: uint32... --> */
|
| /* */
|
| static void
|
| - Ins_SHP( INS_ARG )
|
| + Ins_SHP( TT_ExecContext exc )
|
| {
|
| TT_GlyphZoneRec zp;
|
| FT_UShort refp;
|
|
|
| - FT_F26Dot6 dx,
|
| - dy;
|
| + FT_F26Dot6 dx, dy;
|
| FT_UShort point;
|
|
|
| - FT_UNUSED_ARG;
|
|
|
| -
|
| - if ( CUR.top < CUR.GS.loop )
|
| + if ( exc->top < exc->GS.loop )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
|
| + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
|
| return;
|
|
|
| - while ( CUR.GS.loop > 0 )
|
| + while ( exc->GS.loop > 0 )
|
| {
|
| - CUR.args--;
|
| - point = (FT_UShort)CUR.stack[CUR.args];
|
| + exc->args--;
|
| + point = (FT_UShort)exc->stack[exc->args];
|
|
|
| - if ( BOUNDS( point, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( point, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| }
|
| else
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| /* doesn't follow Cleartype spec but produces better result */
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode )
|
| - MOVE_Zp2_Point( point, 0, dy, TRUE );
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode )
|
| + Move_Zp2_Point( exc, point, 0, dy, TRUE );
|
| else
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| - MOVE_Zp2_Point( point, dx, dy, TRUE );
|
| + Move_Zp2_Point( exc, point, dx, dy, TRUE );
|
|
|
| - CUR.GS.loop--;
|
| + exc->GS.loop--;
|
| }
|
|
|
| Fail:
|
| - CUR.GS.loop = 1;
|
| - CUR.new_top = CUR.args;
|
| + exc->GS.loop = 1;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -5997,7 +5532,8 @@
|
| /* zero which includes all points of it. */
|
| /* */
|
| static void
|
| - Ins_SHC( INS_ARG )
|
| + Ins_SHC( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| TT_GlyphZoneRec zp;
|
| FT_UShort refp;
|
| @@ -6007,36 +5543,36 @@
|
| FT_UShort start, limit, i;
|
|
|
|
|
| - contour = (FT_UShort)args[0];
|
| - bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
|
| + contour = (FT_Short)args[0];
|
| + bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
|
|
|
| if ( BOUNDS( contour, bounds ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
|
| + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
|
| return;
|
|
|
| if ( contour == 0 )
|
| start = 0;
|
| else
|
| - start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
|
| - CUR.zp2.first_point );
|
| + start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
|
| + exc->zp2.first_point );
|
|
|
| /* we use the number of points if in the twilight zone */
|
| - if ( CUR.GS.gep2 == 0 )
|
| - limit = CUR.zp2.n_points;
|
| + if ( exc->GS.gep2 == 0 )
|
| + limit = exc->zp2.n_points;
|
| else
|
| - limit = (FT_UShort)( CUR.zp2.contours[contour] -
|
| - CUR.zp2.first_point + 1 );
|
| + limit = (FT_UShort)( exc->zp2.contours[contour] -
|
| + exc->zp2.first_point + 1 );
|
|
|
| for ( i = start; i < limit; i++ )
|
| {
|
| - if ( zp.cur != CUR.zp2.cur || refp != i )
|
| - MOVE_Zp2_Point( i, dx, dy, TRUE );
|
| + if ( zp.cur != exc->zp2.cur || refp != i )
|
| + Move_Zp2_Point( exc, i, dx, dy, TRUE );
|
| }
|
| }
|
|
|
| @@ -6048,7 +5584,8 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_SHZ( INS_ARG )
|
| + Ins_SHZ( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| TT_GlyphZoneRec zp;
|
| FT_UShort refp;
|
| @@ -6060,30 +5597,30 @@
|
|
|
| if ( BOUNDS( args[0], 2 ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
|
| + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
|
| return;
|
|
|
| /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
|
| /* Twilight zone has no real contours, so use `n_points'. */
|
| /* Normal zone's `n_points' includes phantoms, so must */
|
| /* use end of last contour. */
|
| - if ( CUR.GS.gep2 == 0 )
|
| - limit = (FT_UShort)CUR.zp2.n_points;
|
| - else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
|
| - limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
|
| + if ( exc->GS.gep2 == 0 )
|
| + limit = (FT_UShort)exc->zp2.n_points;
|
| + else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
|
| + limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
|
| else
|
| limit = 0;
|
|
|
| /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
|
| for ( i = 0; i < limit; i++ )
|
| {
|
| - if ( zp.cur != CUR.zp2.cur || refp != i )
|
| - MOVE_Zp2_Point( i, dx, dy, FALSE );
|
| + if ( zp.cur != exc->zp2.cur || refp != i )
|
| + Move_Zp2_Point( exc, i, dx, dy, FALSE );
|
| }
|
| }
|
|
|
| @@ -6095,7 +5632,8 @@
|
| /* Stack: f26.6 uint32... --> */
|
| /* */
|
| static void
|
| - Ins_SHPIX( INS_ARG )
|
| + Ins_SHPIX( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_F26Dot6 dx, dy;
|
| FT_UShort point;
|
| @@ -6104,17 +5642,17 @@
|
| #endif
|
|
|
|
|
| - if ( CUR.top < CUR.GS.loop + 1 )
|
| + if ( exc->top < exc->GS.loop + 1 )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| - if ( CUR.GS.both_x_axis )
|
| + if ( exc->GS.both_x_axis )
|
| {
|
| dx = (FT_UInt32)args[0];
|
| dy = 0;
|
| @@ -6128,115 +5666,115 @@
|
| else
|
| #endif
|
| {
|
| - dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
|
| - dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
|
| + dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
|
| + dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
|
| }
|
|
|
| - while ( CUR.GS.loop > 0 )
|
| + while ( exc->GS.loop > 0 )
|
| {
|
| - CUR.args--;
|
| + exc->args--;
|
|
|
| - point = (FT_UShort)CUR.stack[CUR.args];
|
| + point = (FT_UShort)exc->stack[exc->args];
|
|
|
| - if ( BOUNDS( point, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( point, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| }
|
| else
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| {
|
| - /* If not using ignore_x_mode rendering, allow ZP2 move. */
|
| - /* If inline deltas aren't allowed, skip ZP2 move. */
|
| - /* If using ignore_x_mode rendering, allow ZP2 point move if: */
|
| - /* - freedom vector is y and sph_compatibility_mode is off */
|
| - /* - the glyph is composite and the move is in the Y direction */
|
| - /* - the glyph is specifically set to allow SHPIX moves */
|
| - /* - the move is on a previously Y-touched point */
|
| -
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode )
|
| + /* If not using ignore_x_mode rendering, allow ZP2 move. */
|
| + /* If inline deltas aren't allowed, skip ZP2 move. */
|
| + /* If using ignore_x_mode rendering, allow ZP2 point move if: */
|
| + /* - freedom vector is y and sph_compatibility_mode is off */
|
| + /* - the glyph is composite and the move is in the Y direction */
|
| + /* - the glyph is specifically set to allow SHPIX moves */
|
| + /* - the move is on a previously Y-touched point */
|
| +
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode )
|
| {
|
| /* save point for later comparison */
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| - B1 = CUR.zp2.cur[point].y;
|
| + if ( exc->GS.freeVector.y != 0 )
|
| + B1 = exc->zp2.cur[point].y;
|
| else
|
| - B1 = CUR.zp2.cur[point].x;
|
| + B1 = exc->zp2.cur[point].x;
|
|
|
| - if ( !CUR.face->sph_compatibility_mode &&
|
| - CUR.GS.freeVector.y != 0 )
|
| + if ( !exc->face->sph_compatibility_mode &&
|
| + exc->GS.freeVector.y != 0 )
|
| {
|
| - MOVE_Zp2_Point( point, dx, dy, TRUE );
|
| + Move_Zp2_Point( exc, point, dx, dy, TRUE );
|
|
|
| /* save new point */
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| + if ( exc->GS.freeVector.y != 0 )
|
| {
|
| - B2 = CUR.zp2.cur[point].y;
|
| + B2 = exc->zp2.cur[point].y;
|
|
|
| /* reverse any disallowed moves */
|
| - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
|
| - ( B1 & 63 ) != 0 &&
|
| - ( B2 & 63 ) != 0 &&
|
| - B1 != B2 )
|
| - MOVE_Zp2_Point( point, -dx, -dy, TRUE );
|
| + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
|
| + ( B1 & 63 ) != 0 &&
|
| + ( B2 & 63 ) != 0 &&
|
| + B1 != B2 )
|
| + Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
|
| }
|
| }
|
| - else if ( CUR.face->sph_compatibility_mode )
|
| + else if ( exc->face->sph_compatibility_mode )
|
| {
|
| - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
|
| + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
|
| {
|
| dx = FT_PIX_ROUND( B1 + dx ) - B1;
|
| dy = FT_PIX_ROUND( B1 + dy ) - B1;
|
| }
|
|
|
| /* skip post-iup deltas */
|
| - if ( CUR.iup_called &&
|
| - ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
|
| - ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
|
| + if ( exc->iup_called &&
|
| + ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
|
| + ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
|
| goto Skip;
|
|
|
| - if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
|
| - ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
|
| - ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
|
| - MOVE_Zp2_Point( point, 0, dy, TRUE );
|
| + if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
|
| + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
|
| + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
|
| + Move_Zp2_Point( exc, point, 0, dy, TRUE );
|
|
|
| /* save new point */
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| + if ( exc->GS.freeVector.y != 0 )
|
| {
|
| - B2 = CUR.zp2.cur[point].y;
|
| + B2 = exc->zp2.cur[point].y;
|
|
|
| /* reverse any disallowed moves */
|
| if ( ( B1 & 63 ) == 0 &&
|
| ( B2 & 63 ) != 0 &&
|
| B1 != B2 )
|
| - MOVE_Zp2_Point( point, 0, -dy, TRUE );
|
| + Move_Zp2_Point( exc, point, 0, -dy, TRUE );
|
| }
|
| }
|
| - else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
|
| - MOVE_Zp2_Point( point, dx, dy, TRUE );
|
| + else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
|
| + Move_Zp2_Point( exc, point, dx, dy, TRUE );
|
| }
|
| else
|
| - MOVE_Zp2_Point( point, dx, dy, TRUE );
|
| + Move_Zp2_Point( exc, point, dx, dy, TRUE );
|
| }
|
|
|
| Skip:
|
|
|
| #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - MOVE_Zp2_Point( point, dx, dy, TRUE );
|
| + Move_Zp2_Point( exc, point, dx, dy, TRUE );
|
|
|
| #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - CUR.GS.loop--;
|
| + exc->GS.loop--;
|
| }
|
|
|
| Fail:
|
| - CUR.GS.loop = 1;
|
| - CUR.new_top = CUR.args;
|
| + exc->GS.loop = 1;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -6247,7 +5785,8 @@
|
| /* Stack: f26.6 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_MSIRP( INS_ARG )
|
| + Ins_MSIRP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point;
|
| FT_F26Dot6 distance;
|
| @@ -6258,11 +5797,11 @@
|
|
|
| if ( SUBPIXEL_HINTING )
|
| {
|
| - control_value_cutin = CUR.GS.control_value_cutin;
|
| + control_value_cutin = exc->GS.control_value_cutin;
|
|
|
| - if ( CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| + if ( exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 &&
|
| + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| control_value_cutin = 0;
|
| }
|
|
|
| @@ -6270,42 +5809,41 @@
|
|
|
| point = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( point, CUR.zp1.n_points ) ||
|
| - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( point, exc->zp1.n_points ) ||
|
| + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| /* UNDOCUMENTED! The MS rasterizer does that with */
|
| /* twilight points (confirmed by Greg Hitchcock) */
|
| - if ( CUR.GS.gep1 == 0 )
|
| + if ( exc->GS.gep1 == 0 )
|
| {
|
| - CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
|
| - CUR_Func_move_orig( &CUR.zp1, point, args[1] );
|
| - CUR.zp1.cur[point] = CUR.zp1.org[point];
|
| + exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
|
| + exc->func_move_orig( exc, &exc->zp1, point, args[1] );
|
| + exc->zp1.cur[point] = exc->zp1.org[point];
|
| }
|
|
|
| - distance = CUR_Func_project( CUR.zp1.cur + point,
|
| - CUR.zp0.cur + CUR.GS.rp0 );
|
| + distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| /* subpixel hinting - make MSIRP respect CVT cut-in; */
|
| if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 &&
|
| FT_ABS( distance - args[1] ) >= control_value_cutin )
|
| distance = args[1];
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - CUR_Func_move( &CUR.zp1, point, args[1] - distance );
|
| + exc->func_move( exc, &exc->zp1, point, args[1] - distance );
|
|
|
| - CUR.GS.rp1 = CUR.GS.rp0;
|
| - CUR.GS.rp2 = point;
|
| + exc->GS.rp1 = exc->GS.rp0;
|
| + exc->GS.rp2 = point;
|
|
|
| - if ( ( CUR.opcode & 1 ) != 0 )
|
| - CUR.GS.rp0 = point;
|
| + if ( ( exc->opcode & 1 ) != 0 )
|
| + exc->GS.rp0 = point;
|
| }
|
|
|
|
|
| @@ -6316,7 +5854,8 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_MDAP( INS_ARG )
|
| + Ins_MDAP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point;
|
| FT_F26Dot6 cur_dist;
|
| @@ -6325,36 +5864,38 @@
|
|
|
| point = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( point, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( point, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - if ( ( CUR.opcode & 1 ) != 0 )
|
| + if ( ( exc->opcode & 1 ) != 0 )
|
| {
|
| - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
|
| + cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 )
|
| - distance = ROUND_None(
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 )
|
| + distance = Round_None(
|
| + exc,
|
| cur_dist,
|
| - CUR.tt_metrics.compensations[0] ) - cur_dist;
|
| + exc->tt_metrics.compensations[0] ) - cur_dist;
|
| else
|
| #endif
|
| - distance = CUR_Func_round(
|
| + distance = exc->func_round(
|
| + exc,
|
| cur_dist,
|
| - CUR.tt_metrics.compensations[0] ) - cur_dist;
|
| + exc->tt_metrics.compensations[0] ) - cur_dist;
|
| }
|
| else
|
| distance = 0;
|
|
|
| - CUR_Func_move( &CUR.zp0, point, distance );
|
| + exc->func_move( exc, &exc->zp0, point, distance );
|
|
|
| - CUR.GS.rp0 = point;
|
| - CUR.GS.rp1 = point;
|
| + exc->GS.rp0 = point;
|
| + exc->GS.rp1 = point;
|
| }
|
|
|
|
|
| @@ -6365,7 +5906,8 @@
|
| /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_MIAP( INS_ARG )
|
| + Ins_MIAP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_ULong cvtEntry;
|
| FT_UShort point;
|
| @@ -6374,24 +5916,24 @@
|
| FT_F26Dot6 control_value_cutin;
|
|
|
|
|
| - control_value_cutin = CUR.GS.control_value_cutin;
|
| + control_value_cutin = exc->GS.control_value_cutin;
|
| cvtEntry = (FT_ULong)args[1];
|
| point = (FT_UShort)args[0];
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 &&
|
| - CUR.GS.freeVector.y == 0 &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 &&
|
| + exc->GS.freeVector.y == 0 &&
|
| + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| control_value_cutin = 0;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - if ( BOUNDS( point, CUR.zp0.n_points ) ||
|
| - BOUNDSL( cvtEntry, CUR.cvtSize ) )
|
| + if ( BOUNDS( point, exc->zp0.n_points ) ||
|
| + BOUNDSL( cvtEntry, exc->cvtSize ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| @@ -6415,56 +5957,58 @@
|
| /* */
|
| /* Confirmed by Greg Hitchcock. */
|
|
|
| - distance = CUR_Func_read_cvt( cvtEntry );
|
| + distance = exc->func_read_cvt( exc, cvtEntry );
|
|
|
| - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */
|
| + if ( exc->GS.gep0 == 0 ) /* If in twilight zone */
|
| {
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
|
| /* Determined via experimentation and may be incorrect... */
|
| - if ( !SUBPIXEL_HINTING ||
|
| - ( !CUR.ignore_x_mode ||
|
| - !CUR.face->sph_compatibility_mode ) )
|
| + if ( !SUBPIXEL_HINTING ||
|
| + ( !exc->ignore_x_mode ||
|
| + !exc->face->sph_compatibility_mode ) )
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
|
| - CUR.GS.freeVector.x );
|
| - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
|
| - CUR.GS.freeVector.y ),
|
| - CUR.zp0.cur[point] = CUR.zp0.org[point];
|
| + exc->zp0.org[point].x = TT_MulFix14( distance,
|
| + exc->GS.freeVector.x );
|
| + exc->zp0.org[point].y = TT_MulFix14( distance,
|
| + exc->GS.freeVector.y ),
|
| + exc->zp0.cur[point] = exc->zp0.org[point];
|
| }
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
|
| - distance > 0 &&
|
| - CUR.GS.freeVector.y != 0 )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
|
| + distance > 0 &&
|
| + exc->GS.freeVector.y != 0 )
|
| distance = 0;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
|
| + org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
|
|
|
| - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
|
| + if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
|
| {
|
| if ( FT_ABS( distance - org_dist ) > control_value_cutin )
|
| distance = org_dist;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 )
|
| - distance = ROUND_None( distance,
|
| - CUR.tt_metrics.compensations[0] );
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 )
|
| + distance = Round_None( exc,
|
| + distance,
|
| + exc->tt_metrics.compensations[0] );
|
| else
|
| #endif
|
| - distance = CUR_Func_round( distance,
|
| - CUR.tt_metrics.compensations[0] );
|
| + distance = exc->func_round( exc,
|
| + distance,
|
| + exc->tt_metrics.compensations[0] );
|
| }
|
|
|
| - CUR_Func_move( &CUR.zp0, point, distance - org_dist );
|
| + exc->func_move( exc, &exc->zp0, point, distance - org_dist );
|
|
|
| Fail:
|
| - CUR.GS.rp0 = point;
|
| - CUR.GS.rp1 = point;
|
| + exc->GS.rp0 = point;
|
| + exc->GS.rp1 = point;
|
| }
|
|
|
|
|
| @@ -6475,29 +6019,30 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_MDRP( INS_ARG )
|
| + Ins_MDRP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point;
|
| FT_F26Dot6 org_dist, distance, minimum_distance;
|
|
|
|
|
| - minimum_distance = CUR.GS.minimum_distance;
|
| + minimum_distance = exc->GS.minimum_distance;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 &&
|
| + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| minimum_distance = 0;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| point = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( point, CUR.zp1.n_points ) ||
|
| - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( point, exc->zp1.n_points ) ||
|
| + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| @@ -6506,74 +6051,77 @@
|
|
|
| /* XXX: UNDOCUMENTED: twilight zone special case */
|
|
|
| - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
|
| + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
|
| {
|
| - FT_Vector* vec1 = &CUR.zp1.org[point];
|
| - FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0];
|
| + FT_Vector* vec1 = &exc->zp1.org[point];
|
| + FT_Vector* vec2 = &exc->zp0.org[exc->GS.rp0];
|
|
|
|
|
| - org_dist = CUR_Func_dualproj( vec1, vec2 );
|
| + org_dist = DUALPROJ( vec1, vec2 );
|
| }
|
| else
|
| {
|
| - FT_Vector* vec1 = &CUR.zp1.orus[point];
|
| - FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0];
|
| + FT_Vector* vec1 = &exc->zp1.orus[point];
|
| + FT_Vector* vec2 = &exc->zp0.orus[exc->GS.rp0];
|
|
|
|
|
| - if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
|
| + if ( exc->metrics.x_scale == exc->metrics.y_scale )
|
| {
|
| /* this should be faster */
|
| - org_dist = CUR_Func_dualproj( vec1, vec2 );
|
| - org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
|
| + org_dist = DUALPROJ( vec1, vec2 );
|
| + org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
|
| }
|
| else
|
| {
|
| FT_Vector vec;
|
|
|
|
|
| - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
|
| - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
|
| + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
|
| + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
|
|
|
| - org_dist = CUR_fast_dualproj( &vec );
|
| + org_dist = FAST_DUALPROJ( &vec );
|
| }
|
| }
|
|
|
| /* single width cut-in test */
|
|
|
| - if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <
|
| - CUR.GS.single_width_cutin )
|
| + if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
|
| + exc->GS.single_width_cutin )
|
| {
|
| if ( org_dist >= 0 )
|
| - org_dist = CUR.GS.single_width_value;
|
| + org_dist = exc->GS.single_width_value;
|
| else
|
| - org_dist = -CUR.GS.single_width_value;
|
| + org_dist = -exc->GS.single_width_value;
|
| }
|
|
|
| /* round flag */
|
|
|
| - if ( ( CUR.opcode & 4 ) != 0 )
|
| + if ( ( exc->opcode & 4 ) != 0 )
|
| {
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 )
|
| - distance = ROUND_None(
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 )
|
| + distance = Round_None(
|
| + exc,
|
| org_dist,
|
| - CUR.tt_metrics.compensations[CUR.opcode & 3] );
|
| + exc->tt_metrics.compensations[exc->opcode & 3] );
|
| else
|
| #endif
|
| - distance = CUR_Func_round(
|
| - org_dist,
|
| - CUR.tt_metrics.compensations[CUR.opcode & 3] );
|
| + distance = exc->func_round(
|
| + exc,
|
| + org_dist,
|
| + exc->tt_metrics.compensations[exc->opcode & 3] );
|
| }
|
| else
|
| - distance = ROUND_None(
|
| + distance = Round_None(
|
| + exc,
|
| org_dist,
|
| - CUR.tt_metrics.compensations[CUR.opcode & 3] );
|
| + exc->tt_metrics.compensations[exc->opcode & 3] );
|
|
|
| /* minimum distance flag */
|
|
|
| - if ( ( CUR.opcode & 8 ) != 0 )
|
| + if ( ( exc->opcode & 8 ) != 0 )
|
| {
|
| if ( org_dist >= 0 )
|
| {
|
| @@ -6589,17 +6137,16 @@
|
|
|
| /* now move the point */
|
|
|
| - org_dist = CUR_Func_project( CUR.zp1.cur + point,
|
| - CUR.zp0.cur + CUR.GS.rp0 );
|
| + org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
|
|
|
| - CUR_Func_move( &CUR.zp1, point, distance - org_dist );
|
| + exc->func_move( exc, &exc->zp1, point, distance - org_dist );
|
|
|
| Fail:
|
| - CUR.GS.rp1 = CUR.GS.rp0;
|
| - CUR.GS.rp2 = point;
|
| + exc->GS.rp1 = exc->GS.rp0;
|
| + exc->GS.rp2 = point;
|
|
|
| - if ( ( CUR.opcode & 16 ) != 0 )
|
| - CUR.GS.rp0 = point;
|
| + if ( ( exc->opcode & 16 ) != 0 )
|
| + exc->GS.rp0 = point;
|
| }
|
|
|
|
|
| @@ -6610,7 +6157,8 @@
|
| /* Stack: int32? uint32 --> */
|
| /* */
|
| static void
|
| - Ins_MIRP( INS_ARG )
|
| + Ins_MIRP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point;
|
| FT_ULong cvtEntry;
|
| @@ -6628,77 +6176,75 @@
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
|
|
| - minimum_distance = CUR.GS.minimum_distance;
|
| - control_value_cutin = CUR.GS.control_value_cutin;
|
| + minimum_distance = exc->GS.minimum_distance;
|
| + control_value_cutin = exc->GS.control_value_cutin;
|
| point = (FT_UShort)args[0];
|
| cvtEntry = (FT_ULong)( args[1] + 1 );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.x != 0 &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.x != 0 &&
|
| + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
|
| control_value_cutin = minimum_distance = 0;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
|
|
|
| - if ( BOUNDS( point, CUR.zp1.n_points ) ||
|
| - BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) ||
|
| - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( point, exc->zp1.n_points ) ||
|
| + BOUNDSL( cvtEntry, exc->cvtSize + 1 ) ||
|
| + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| if ( !cvtEntry )
|
| cvt_dist = 0;
|
| else
|
| - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
|
| + cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
|
|
|
| /* single width test */
|
|
|
| - if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
|
| - CUR.GS.single_width_cutin )
|
| + if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
|
| + exc->GS.single_width_cutin )
|
| {
|
| if ( cvt_dist >= 0 )
|
| - cvt_dist = CUR.GS.single_width_value;
|
| + cvt_dist = exc->GS.single_width_value;
|
| else
|
| - cvt_dist = -CUR.GS.single_width_value;
|
| + cvt_dist = -exc->GS.single_width_value;
|
| }
|
|
|
| /* UNDOCUMENTED! The MS rasterizer does that with */
|
| /* twilight points (confirmed by Greg Hitchcock) */
|
| - if ( CUR.GS.gep1 == 0 )
|
| + if ( exc->GS.gep1 == 0 )
|
| {
|
| - CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
|
| - TT_MulFix14( (FT_UInt32)cvt_dist,
|
| - CUR.GS.freeVector.x );
|
| - CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
|
| - TT_MulFix14( (FT_UInt32)cvt_dist,
|
| - CUR.GS.freeVector.y );
|
| - CUR.zp1.cur[point] = CUR.zp1.org[point];
|
| + exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
|
| + TT_MulFix14( cvt_dist,
|
| + exc->GS.freeVector.x );
|
| + exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
|
| + TT_MulFix14( cvt_dist,
|
| + exc->GS.freeVector.y );
|
| + exc->zp1.cur[point] = exc->zp1.org[point];
|
| }
|
|
|
| - org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
|
| - &CUR.zp0.org[CUR.GS.rp0] );
|
| - cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
|
| - &CUR.zp0.cur[CUR.GS.rp0] );
|
| + org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
|
| + cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
|
|
|
| /* auto-flip test */
|
|
|
| - if ( CUR.GS.auto_flip )
|
| + if ( exc->GS.auto_flip )
|
| {
|
| if ( ( org_dist ^ cvt_dist ) < 0 )
|
| cvt_dist = -cvt_dist;
|
| }
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.y != 0 &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.freeVector.y != 0 &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
|
| {
|
| if ( cur_dist < -64 )
|
| cvt_dist -= 16;
|
| @@ -6709,12 +6255,12 @@
|
|
|
| /* control value cut-in and round */
|
|
|
| - if ( ( CUR.opcode & 4 ) != 0 )
|
| + if ( ( exc->opcode & 4 ) != 0 )
|
| {
|
| /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */
|
| /* refer to the same zone. */
|
|
|
| - if ( CUR.GS.gep0 == CUR.GS.gep1 )
|
| + if ( exc->GS.gep0 == exc->GS.gep1 )
|
| {
|
| /* XXX: According to Greg Hitchcock, the following wording is */
|
| /* the right one: */
|
| @@ -6732,32 +6278,34 @@
|
| cvt_dist = org_dist;
|
| }
|
|
|
| - distance = CUR_Func_round(
|
| + distance = exc->func_round(
|
| + exc,
|
| cvt_dist,
|
| - CUR.tt_metrics.compensations[CUR.opcode & 3] );
|
| + exc->tt_metrics.compensations[exc->opcode & 3] );
|
| }
|
| else
|
| {
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| /* do cvt cut-in always in MIRP for sph */
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.GS.gep0 == CUR.GS.gep1 )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->GS.gep0 == exc->GS.gep1 )
|
| {
|
| if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
|
| cvt_dist = org_dist;
|
| }
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - distance = ROUND_None(
|
| + distance = Round_None(
|
| + exc,
|
| cvt_dist,
|
| - CUR.tt_metrics.compensations[CUR.opcode & 3] );
|
| + exc->tt_metrics.compensations[exc->opcode & 3] );
|
| }
|
|
|
| /* minimum distance test */
|
|
|
| - if ( ( CUR.opcode & 8 ) != 0 )
|
| + if ( ( exc->opcode & 8 ) != 0 )
|
| {
|
| if ( org_dist >= 0 )
|
| {
|
| @@ -6774,59 +6322,59 @@
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| if ( SUBPIXEL_HINTING )
|
| {
|
| - B1 = CUR.zp1.cur[point].y;
|
| + B1 = exc->zp1.cur[point].y;
|
|
|
| /* Round moves if necessary */
|
| - if ( CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.y != 0 &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
|
| + if ( exc->ignore_x_mode &&
|
| + exc->GS.freeVector.y != 0 &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
|
| distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
|
|
|
| - if ( CUR.ignore_x_mode &&
|
| - CUR.GS.freeVector.y != 0 &&
|
| - ( CUR.opcode & 16 ) == 0 &&
|
| - ( CUR.opcode & 8 ) == 0 &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
|
| + if ( exc->ignore_x_mode &&
|
| + exc->GS.freeVector.y != 0 &&
|
| + ( exc->opcode & 16 ) == 0 &&
|
| + ( exc->opcode & 8 ) == 0 &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
|
| distance += 64;
|
| }
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
|
| + exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| if ( SUBPIXEL_HINTING )
|
| {
|
| - B2 = CUR.zp1.cur[point].y;
|
| + B2 = exc->zp1.cur[point].y;
|
|
|
| /* Reverse move if necessary */
|
| - if ( CUR.ignore_x_mode )
|
| + if ( exc->ignore_x_mode )
|
| {
|
| - if ( CUR.face->sph_compatibility_mode &&
|
| - CUR.GS.freeVector.y != 0 &&
|
| - ( B1 & 63 ) == 0 &&
|
| - ( B2 & 63 ) != 0 )
|
| + if ( exc->face->sph_compatibility_mode &&
|
| + exc->GS.freeVector.y != 0 &&
|
| + ( B1 & 63 ) == 0 &&
|
| + ( B2 & 63 ) != 0 )
|
| reverse_move = TRUE;
|
|
|
| - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
|
| - CUR.GS.freeVector.y != 0 &&
|
| - ( B2 & 63 ) != 0 &&
|
| - ( B1 & 63 ) != 0 )
|
| + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
|
| + exc->GS.freeVector.y != 0 &&
|
| + ( B2 & 63 ) != 0 &&
|
| + ( B1 & 63 ) != 0 )
|
| reverse_move = TRUE;
|
| }
|
|
|
| if ( reverse_move )
|
| - CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
|
| + exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
|
| }
|
|
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| Fail:
|
| - CUR.GS.rp1 = CUR.GS.rp0;
|
| + exc->GS.rp1 = exc->GS.rp0;
|
|
|
| - if ( ( CUR.opcode & 16 ) != 0 )
|
| - CUR.GS.rp0 = point;
|
| + if ( ( exc->opcode & 16 ) != 0 )
|
| + exc->GS.rp0 = point;
|
|
|
| - CUR.GS.rp2 = point;
|
| + exc->GS.rp2 = point;
|
| }
|
|
|
|
|
| @@ -6837,61 +6385,59 @@
|
| /* Stack: uint32 uint32... --> */
|
| /* */
|
| static void
|
| - Ins_ALIGNRP( INS_ARG )
|
| + Ins_ALIGNRP( TT_ExecContext exc )
|
| {
|
| FT_UShort point;
|
| FT_F26Dot6 distance;
|
|
|
| - FT_UNUSED_ARG;
|
| -
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.iup_called &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->iup_called &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - if ( CUR.top < CUR.GS.loop ||
|
| - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
|
| + if ( exc->top < exc->GS.loop ||
|
| + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| - while ( CUR.GS.loop > 0 )
|
| + while ( exc->GS.loop > 0 )
|
| {
|
| - CUR.args--;
|
| + exc->args--;
|
|
|
| - point = (FT_UShort)CUR.stack[CUR.args];
|
| + point = (FT_UShort)exc->stack[exc->args];
|
|
|
| - if ( BOUNDS( point, CUR.zp1.n_points ) )
|
| + if ( BOUNDS( point, exc->zp1.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| }
|
| else
|
| {
|
| - distance = CUR_Func_project( CUR.zp1.cur + point,
|
| - CUR.zp0.cur + CUR.GS.rp0 );
|
| + distance = PROJECT( exc->zp1.cur + point,
|
| + exc->zp0.cur + exc->GS.rp0 );
|
|
|
| - CUR_Func_move( &CUR.zp1, point, -distance );
|
| + exc->func_move( exc, &exc->zp1, point, -distance );
|
| }
|
|
|
| - CUR.GS.loop--;
|
| + exc->GS.loop--;
|
| }
|
|
|
| Fail:
|
| - CUR.GS.loop = 1;
|
| - CUR.new_top = CUR.args;
|
| + exc->GS.loop = 1;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -6902,7 +6448,8 @@
|
| /* Stack: 5 * uint32 --> */
|
| /* */
|
| static void
|
| - Ins_ISECT( INS_ARG )
|
| + Ins_ISECT( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point,
|
| a0, a1,
|
| @@ -6926,29 +6473,27 @@
|
| b0 = (FT_UShort)args[3];
|
| b1 = (FT_UShort)args[4];
|
|
|
| - if ( BOUNDS( b0, CUR.zp0.n_points ) ||
|
| - BOUNDS( b1, CUR.zp0.n_points ) ||
|
| - BOUNDS( a0, CUR.zp1.n_points ) ||
|
| - BOUNDS( a1, CUR.zp1.n_points ) ||
|
| - BOUNDS( point, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( b0, exc->zp0.n_points ) ||
|
| + BOUNDS( b1, exc->zp0.n_points ) ||
|
| + BOUNDS( a0, exc->zp1.n_points ) ||
|
| + BOUNDS( a1, exc->zp1.n_points ) ||
|
| + BOUNDS( point, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| /* Cramer's rule */
|
|
|
| - dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
|
| - dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
|
| + dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
|
| + dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
|
|
|
| - dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
|
| - day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
|
| + dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
|
| + day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
|
|
|
| - dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
|
| - dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
|
| -
|
| - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
|
| + dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
|
| + dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
|
|
|
| discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
|
| FT_MulDiv( day, dbx, 0x40 );
|
| @@ -6970,22 +6515,24 @@
|
| R.x = FT_MulDiv( val, dax, discriminant );
|
| R.y = FT_MulDiv( val, day, discriminant );
|
|
|
| - CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
|
| - CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
|
| + exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
|
| + exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
|
| }
|
| else
|
| {
|
| /* else, take the middle of the middles of A and B */
|
|
|
| - CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
|
| - CUR.zp1.cur[a1].x +
|
| - CUR.zp0.cur[b0].x +
|
| - CUR.zp0.cur[b1].x ) / 4;
|
| - CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
|
| - CUR.zp1.cur[a1].y +
|
| - CUR.zp0.cur[b0].y +
|
| - CUR.zp0.cur[b1].y ) / 4;
|
| + exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
|
| + exc->zp1.cur[a1].x +
|
| + exc->zp0.cur[b0].x +
|
| + exc->zp0.cur[b1].x ) / 4;
|
| + exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
|
| + exc->zp1.cur[a1].y +
|
| + exc->zp0.cur[b0].y +
|
| + exc->zp0.cur[b1].y ) / 4;
|
| }
|
| +
|
| + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
|
| }
|
|
|
|
|
| @@ -6996,7 +6543,8 @@
|
| /* Stack: uint32 uint32 --> */
|
| /* */
|
| static void
|
| - Ins_ALIGNPTS( INS_ARG )
|
| + Ins_ALIGNPTS( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort p1, p2;
|
| FT_F26Dot6 distance;
|
| @@ -7005,19 +6553,18 @@
|
| p1 = (FT_UShort)args[0];
|
| p2 = (FT_UShort)args[1];
|
|
|
| - if ( BOUNDS( p1, CUR.zp1.n_points ) ||
|
| - BOUNDS( p2, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( p1, exc->zp1.n_points ) ||
|
| + BOUNDS( p2, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| - distance = CUR_Func_project( CUR.zp0.cur + p2,
|
| - CUR.zp1.cur + p1 ) / 2;
|
| + distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
|
|
|
| - CUR_Func_move( &CUR.zp1, p1, distance );
|
| - CUR_Func_move( &CUR.zp0, p2, -distance );
|
| + exc->func_move( exc, &exc->zp1, p1, distance );
|
| + exc->func_move( exc, &exc->zp0, p2, -distance );
|
| }
|
|
|
|
|
| @@ -7031,50 +6578,48 @@
|
| /* SOMETIMES, DUMBER CODE IS BETTER CODE */
|
|
|
| static void
|
| - Ins_IP( INS_ARG )
|
| + Ins_IP( TT_ExecContext exc )
|
| {
|
| FT_F26Dot6 old_range, cur_range;
|
| FT_Vector* orus_base;
|
| FT_Vector* cur_base;
|
| FT_Int twilight;
|
|
|
| - FT_UNUSED_ARG;
|
|
|
| -
|
| - if ( CUR.top < CUR.GS.loop )
|
| + if ( exc->top < exc->GS.loop )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| /*
|
| * We need to deal in a special way with the twilight zone.
|
| - * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
|
| + * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
|
| * for every n.
|
| */
|
| - twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
|
| + twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
|
|
|
| - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto Fail;
|
| }
|
|
|
| if ( twilight )
|
| - orus_base = &CUR.zp0.org[CUR.GS.rp1];
|
| + orus_base = &exc->zp0.org[exc->GS.rp1];
|
| else
|
| - orus_base = &CUR.zp0.orus[CUR.GS.rp1];
|
| + orus_base = &exc->zp0.orus[exc->GS.rp1];
|
|
|
| - cur_base = &CUR.zp0.cur[CUR.GS.rp1];
|
| + cur_base = &exc->zp0.cur[exc->GS.rp1];
|
|
|
| /* XXX: There are some glyphs in some braindead but popular */
|
| /* fonts out there (e.g. [aeu]grave in monotype.ttf) */
|
| /* calling IP[] with bad values of rp[12]. */
|
| /* Do something sane when this odd thing happens. */
|
| - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
|
| - BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
|
| + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
|
| + BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
|
| {
|
| old_range = 0;
|
| cur_range = 0;
|
| @@ -7082,62 +6627,60 @@
|
| else
|
| {
|
| if ( twilight )
|
| - old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
|
| - orus_base );
|
| - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
|
| - old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
|
| - orus_base );
|
| + old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base );
|
| + else if ( exc->metrics.x_scale == exc->metrics.y_scale )
|
| + old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base );
|
| else
|
| {
|
| FT_Vector vec;
|
|
|
|
|
| - vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
|
| - CUR.metrics.x_scale );
|
| - vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
|
| - CUR.metrics.y_scale );
|
| + vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
|
| + exc->metrics.x_scale );
|
| + vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
|
| + exc->metrics.y_scale );
|
|
|
| - old_range = CUR_fast_dualproj( &vec );
|
| + old_range = FAST_DUALPROJ( &vec );
|
| }
|
|
|
| - cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
|
| + cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
|
| }
|
|
|
| - for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
|
| + for ( ; exc->GS.loop > 0; --exc->GS.loop )
|
| {
|
| - FT_UInt point = (FT_UInt)CUR.stack[--CUR.args];
|
| + FT_UInt point = (FT_UInt)exc->stack[--exc->args];
|
| FT_F26Dot6 org_dist, cur_dist, new_dist;
|
|
|
|
|
| /* check point bounds */
|
| - if ( BOUNDS( point, CUR.zp2.n_points ) )
|
| + if ( BOUNDS( point, exc->zp2.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| continue;
|
| }
|
|
|
| if ( twilight )
|
| - org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
|
| - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
|
| - org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
|
| + org_dist = DUALPROJ( &exc->zp2.org[point], orus_base );
|
| + else if ( exc->metrics.x_scale == exc->metrics.y_scale )
|
| + org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base );
|
| else
|
| {
|
| FT_Vector vec;
|
|
|
|
|
| - vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
|
| - CUR.metrics.x_scale );
|
| - vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
|
| - CUR.metrics.y_scale );
|
| + vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
|
| + exc->metrics.x_scale );
|
| + vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
|
| + exc->metrics.y_scale );
|
|
|
| - org_dist = CUR_fast_dualproj( &vec );
|
| + org_dist = FAST_DUALPROJ( &vec );
|
| }
|
|
|
| - cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
|
| + cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
|
|
|
| if ( org_dist )
|
| {
|
| @@ -7167,12 +6710,15 @@
|
| else
|
| new_dist = 0;
|
|
|
| - CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
|
| + exc->func_move( exc,
|
| + &exc->zp2,
|
| + (FT_UShort)point,
|
| + new_dist - cur_dist );
|
| }
|
|
|
| Fail:
|
| - CUR.GS.loop = 1;
|
| - CUR.new_top = CUR.args;
|
| + exc->GS.loop = 1;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -7183,7 +6729,8 @@
|
| /* Stack: uint32 --> */
|
| /* */
|
| static void
|
| - Ins_UTP( INS_ARG )
|
| + Ins_UTP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_UShort point;
|
| FT_Byte mask;
|
| @@ -7191,22 +6738,22 @@
|
|
|
| point = (FT_UShort)args[0];
|
|
|
| - if ( BOUNDS( point, CUR.zp0.n_points ) )
|
| + if ( BOUNDS( point, exc->zp0.n_points ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
|
|
| mask = 0xFF;
|
|
|
| - if ( CUR.GS.freeVector.x != 0 )
|
| + if ( exc->GS.freeVector.x != 0 )
|
| mask &= ~FT_CURVE_TAG_TOUCH_X;
|
|
|
| - if ( CUR.GS.freeVector.y != 0 )
|
| + if ( exc->GS.freeVector.y != 0 )
|
| mask &= ~FT_CURVE_TAG_TOUCH_Y;
|
|
|
| - CUR.zp0.tags[point] &= mask;
|
| + exc->zp0.tags[point] &= mask;
|
| }
|
|
|
|
|
| @@ -7251,7 +6798,7 @@
|
| FT_UInt ref2 )
|
| {
|
| FT_UInt i;
|
| - FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2;
|
| + FT_F26Dot6 orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
|
|
|
|
|
| if ( p1 > p2 )
|
| @@ -7281,12 +6828,15 @@
|
|
|
| org1 = worker->orgs[ref1].x;
|
| org2 = worker->orgs[ref2].x;
|
| - delta1 = worker->curs[ref1].x - org1;
|
| - delta2 = worker->curs[ref2].x - org2;
|
| + cur1 = worker->curs[ref1].x;
|
| + cur2 = worker->curs[ref2].x;
|
| + delta1 = cur1 - org1;
|
| + delta2 = cur2 - org2;
|
|
|
| - if ( orus1 == orus2 )
|
| + if ( cur1 == cur2 || orus1 == orus2 )
|
| {
|
| - /* simple shift of untouched points */
|
| +
|
| + /* trivial snap or shift of untouched points */
|
| for ( i = p1; i <= p2; i++ )
|
| {
|
| FT_F26Dot6 x = worker->orgs[i].x;
|
| @@ -7294,9 +6844,13 @@
|
|
|
| if ( x <= org1 )
|
| x += delta1;
|
| - else
|
| +
|
| + else if ( x >= org2 )
|
| x += delta2;
|
|
|
| + else
|
| + x = cur1;
|
| +
|
| worker->curs[i].x = x;
|
| }
|
| }
|
| @@ -7323,12 +6877,10 @@
|
| if ( !scale_valid )
|
| {
|
| scale_valid = 1;
|
| - scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ),
|
| - orus2 - orus1 );
|
| + scale = FT_DivFix( cur2 - cur1, orus2 - orus1 );
|
| }
|
|
|
| - x = ( org1 + delta1 ) +
|
| - FT_MulFix( worker->orus[i].x - orus1, scale );
|
| + x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
|
| }
|
| worker->curs[i].x = x;
|
| }
|
| @@ -7343,7 +6895,7 @@
|
| /* Stack: --> */
|
| /* */
|
| static void
|
| - Ins_IUP( INS_ARG )
|
| + Ins_IUP( TT_ExecContext exc )
|
| {
|
| IUP_WorkerRec V;
|
| FT_Byte mask;
|
| @@ -7357,51 +6909,49 @@
|
| FT_UInt point; /* current point */
|
| FT_Short contour; /* current contour */
|
|
|
| - FT_UNUSED_ARG;
|
| -
|
|
|
| /* ignore empty outlines */
|
| - if ( CUR.pts.n_contours == 0 )
|
| + if ( exc->pts.n_contours == 0 )
|
| return;
|
|
|
| - if ( CUR.opcode & 1 )
|
| + if ( exc->opcode & 1 )
|
| {
|
| mask = FT_CURVE_TAG_TOUCH_X;
|
| - V.orgs = CUR.pts.org;
|
| - V.curs = CUR.pts.cur;
|
| - V.orus = CUR.pts.orus;
|
| + V.orgs = exc->pts.org;
|
| + V.curs = exc->pts.cur;
|
| + V.orus = exc->pts.orus;
|
| }
|
| else
|
| {
|
| mask = FT_CURVE_TAG_TOUCH_Y;
|
| - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );
|
| - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
|
| - V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
|
| + V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
|
| + V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
|
| + V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
|
| }
|
| - V.max_points = CUR.pts.n_points;
|
| + V.max_points = exc->pts.n_points;
|
|
|
| contour = 0;
|
| point = 0;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode )
|
| {
|
| - CUR.iup_called = TRUE;
|
| - if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
|
| + exc->iup_called = TRUE;
|
| + if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
|
| return;
|
| }
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| do
|
| {
|
| - end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
|
| + end_point = exc->pts.contours[contour] - exc->pts.first_point;
|
| first_point = point;
|
|
|
| - if ( BOUNDS ( end_point, CUR.pts.n_points ) )
|
| - end_point = CUR.pts.n_points - 1;
|
| + if ( BOUNDS( end_point, exc->pts.n_points ) )
|
| + end_point = exc->pts.n_points - 1;
|
|
|
| - while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
|
| + while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
|
| point++;
|
|
|
| if ( point <= end_point )
|
| @@ -7413,7 +6963,7 @@
|
|
|
| while ( point <= end_point )
|
| {
|
| - if ( ( CUR.pts.tags[point] & mask ) != 0 )
|
| + if ( ( exc->pts.tags[point] & mask ) != 0 )
|
| {
|
| _iup_worker_interpolate( &V,
|
| cur_touched + 1,
|
| @@ -7445,7 +6995,7 @@
|
| }
|
| }
|
| contour++;
|
| - } while ( contour < CUR.pts.n_contours );
|
| + } while ( contour < exc->pts.n_contours );
|
| }
|
|
|
|
|
| @@ -7456,7 +7006,8 @@
|
| /* Stack: uint32 (2 * uint32)... --> */
|
| /* */
|
| static void
|
| - Ins_DELTAP( INS_ARG )
|
| + Ins_DELTAP( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_ULong nump, k;
|
| FT_UShort A;
|
| @@ -7466,52 +7017,52 @@
|
| FT_UShort B1, B2;
|
|
|
|
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.iup_called &&
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->ignore_x_mode &&
|
| + exc->iup_called &&
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
|
| goto Fail;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| /* Delta hinting is covered by US Patent 5159668. */
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| FT_Long n = args[0] * 2;
|
|
|
|
|
| - if ( CUR.args < n )
|
| + if ( exc->args < n )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| - n = CUR.args;
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| + n = exc->args;
|
| }
|
|
|
| - CUR.args -= n;
|
| - CUR.new_top = CUR.args;
|
| + exc->args -= n;
|
| + exc->new_top = exc->args;
|
| return;
|
| }
|
| #endif
|
|
|
| - P = (FT_ULong)CUR_Func_cur_ppem();
|
| + P = (FT_ULong)exc->func_cur_ppem( exc );
|
| nump = (FT_ULong)args[0]; /* some points theoretically may occur more
|
| than once, thus UShort isn't enough */
|
|
|
| for ( k = 1; k <= nump; k++ )
|
| {
|
| - if ( CUR.args < 2 )
|
| + if ( exc->args < 2 )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| - CUR.args = 0;
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| + exc->args = 0;
|
| goto Fail;
|
| }
|
|
|
| - CUR.args -= 2;
|
| + exc->args -= 2;
|
|
|
| - A = (FT_UShort)CUR.stack[CUR.args + 1];
|
| - B = CUR.stack[CUR.args];
|
| + A = (FT_UShort)exc->stack[exc->args + 1];
|
| + B = exc->stack[exc->args];
|
|
|
| /* XXX: Because some popular fonts contain some invalid DeltaP */
|
| /* instructions, we simply ignore them when the stacked */
|
| @@ -7519,11 +7070,11 @@
|
| /* error. As a delta instruction doesn't change a glyph */
|
| /* in great ways, this shouldn't be a problem. */
|
|
|
| - if ( !BOUNDS( A, CUR.zp0.n_points ) )
|
| + if ( !BOUNDS( A, exc->zp0.n_points ) )
|
| {
|
| C = ( (FT_ULong)B & 0xF0 ) >> 4;
|
|
|
| - switch ( CUR.opcode )
|
| + switch ( exc->opcode )
|
| {
|
| case 0x5D:
|
| break;
|
| @@ -7537,14 +7088,14 @@
|
| break;
|
| }
|
|
|
| - C += CUR.GS.delta_base;
|
| + C += exc->GS.delta_base;
|
|
|
| if ( P == C )
|
| {
|
| B = ( (FT_ULong)B & 0xF ) - 8;
|
| if ( B >= 0 )
|
| B++;
|
| - B *= 1L << ( 6 - CUR.GS.delta_shift );
|
| + B *= 1L << ( 6 - exc->GS.delta_shift );
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| @@ -7558,65 +7109,65 @@
|
| * - glyph is composite and freedom vector is not in subpixel
|
| * direction.
|
| */
|
| - if ( !CUR.ignore_x_mode ||
|
| - ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
|
| - ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
|
| - CUR_Func_move( &CUR.zp0, A, B );
|
| + if ( !exc->ignore_x_mode ||
|
| + ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
|
| + ( exc->is_composite && exc->GS.freeVector.y != 0 ) )
|
| + exc->func_move( exc, &exc->zp0, A, B );
|
|
|
| /* Otherwise, apply subpixel hinting and compatibility mode */
|
| /* rules, always skipping deltas in subpixel direction. */
|
| - else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
|
| + else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
|
| {
|
| /* save the y value of the point now; compare after move */
|
| - B1 = (FT_UShort)CUR.zp0.cur[A].y;
|
| + B1 = (FT_UShort)exc->zp0.cur[A].y;
|
|
|
| /* Standard subpixel hinting: Allow y move for y-touched */
|
| /* points. This messes up DejaVu ... */
|
| - if ( !CUR.face->sph_compatibility_mode &&
|
| - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
|
| - CUR_Func_move( &CUR.zp0, A, B );
|
| + if ( !exc->face->sph_compatibility_mode &&
|
| + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
|
| + exc->func_move( exc, &exc->zp0, A, B );
|
|
|
| /* compatibility mode */
|
| - else if ( CUR.face->sph_compatibility_mode &&
|
| - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
|
| + else if ( exc->face->sph_compatibility_mode &&
|
| + !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
|
| {
|
| - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
|
| + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
|
| B = FT_PIX_ROUND( B1 + B ) - B1;
|
|
|
| /* Allow delta move if using sph_compatibility_mode, */
|
| /* IUP has not been called, and point is touched on Y. */
|
| - if ( !CUR.iup_called &&
|
| - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
|
| - CUR_Func_move( &CUR.zp0, A, B );
|
| + if ( !exc->iup_called &&
|
| + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
|
| + exc->func_move( exc, &exc->zp0, A, B );
|
| }
|
|
|
| - B2 = (FT_UShort)CUR.zp0.cur[A].y;
|
| + B2 = (FT_UShort)exc->zp0.cur[A].y;
|
|
|
| /* Reverse this move if it results in a disallowed move */
|
| - if ( CUR.GS.freeVector.y != 0 &&
|
| - ( ( CUR.face->sph_compatibility_mode &&
|
| + if ( exc->GS.freeVector.y != 0 &&
|
| + ( ( exc->face->sph_compatibility_mode &&
|
| ( B1 & 63 ) == 0 &&
|
| ( B2 & 63 ) != 0 ) ||
|
| - ( ( CUR.sph_tweak_flags &
|
| + ( ( exc->sph_tweak_flags &
|
| SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
|
| ( B1 & 63 ) != 0 &&
|
| ( B2 & 63 ) != 0 ) ) )
|
| - CUR_Func_move( &CUR.zp0, A, -B );
|
| + exc->func_move( exc, &exc->zp0, A, -B );
|
| }
|
| }
|
| else
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| - CUR_Func_move( &CUR.zp0, A, B );
|
| + exc->func_move( exc, &exc->zp0, A, B );
|
| }
|
| }
|
| else
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| }
|
|
|
| Fail:
|
| - CUR.new_top = CUR.args;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -7627,7 +7178,8 @@
|
| /* Stack: uint32 (2 * uint32)... --> */
|
| /* */
|
| static void
|
| - Ins_DELTAC( INS_ARG )
|
| + Ins_DELTAC( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_ULong nump, k;
|
| FT_ULong A, C, P;
|
| @@ -7636,47 +7188,47 @@
|
|
|
| #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
|
| /* Delta hinting is covered by US Patent 5159668. */
|
| - if ( CUR.face->unpatented_hinting )
|
| + if ( exc->face->unpatented_hinting )
|
| {
|
| FT_Long n = args[0] * 2;
|
|
|
|
|
| - if ( CUR.args < n )
|
| + if ( exc->args < n )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| - n = CUR.args;
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| + n = exc->args;
|
| }
|
|
|
| - CUR.args -= n;
|
| - CUR.new_top = CUR.args;
|
| + exc->args -= n;
|
| + exc->new_top = exc->args;
|
| return;
|
| }
|
| #endif
|
|
|
| - P = (FT_ULong)CUR_Func_cur_ppem();
|
| + P = (FT_ULong)exc->func_cur_ppem( exc );
|
| nump = (FT_ULong)args[0];
|
|
|
| for ( k = 1; k <= nump; k++ )
|
| {
|
| - if ( CUR.args < 2 )
|
| + if ( exc->args < 2 )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| - CUR.args = 0;
|
| + if ( exc->pedantic_hinting )
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| + exc->args = 0;
|
| goto Fail;
|
| }
|
|
|
| - CUR.args -= 2;
|
| + exc->args -= 2;
|
|
|
| - A = (FT_ULong)CUR.stack[CUR.args + 1];
|
| - B = CUR.stack[CUR.args];
|
| + A = (FT_ULong)exc->stack[exc->args + 1];
|
| + B = exc->stack[exc->args];
|
|
|
| - if ( BOUNDSL( A, CUR.cvtSize ) )
|
| + if ( BOUNDSL( A, exc->cvtSize ) )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| return;
|
| }
|
| }
|
| @@ -7684,7 +7236,7 @@
|
| {
|
| C = ( (FT_ULong)B & 0xF0 ) >> 4;
|
|
|
| - switch ( CUR.opcode )
|
| + switch ( exc->opcode )
|
| {
|
| case 0x73:
|
| break;
|
| @@ -7698,22 +7250,22 @@
|
| break;
|
| }
|
|
|
| - C += CUR.GS.delta_base;
|
| + C += exc->GS.delta_base;
|
|
|
| if ( P == C )
|
| {
|
| B = ( (FT_ULong)B & 0xF ) - 8;
|
| if ( B >= 0 )
|
| B++;
|
| - B *= 1L << ( 6 - CUR.GS.delta_shift );
|
| + B *= 1L << ( 6 - exc->GS.delta_shift );
|
|
|
| - CUR_Func_move_cvt( A, B );
|
| + exc->func_move_cvt( exc, A, B );
|
| }
|
| }
|
| }
|
|
|
| Fail:
|
| - CUR.new_top = CUR.args;
|
| + exc->new_top = exc->args;
|
| }
|
|
|
|
|
| @@ -7730,8 +7282,17 @@
|
| /* Opcode range: 0x88 */
|
| /* Stack: uint32 --> uint32 */
|
| /* */
|
| + /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */
|
| + /* 2015) not documented in the OpenType specification. */
|
| + /* */
|
| + /* Selector bit 11 is incorrectly described as bit 8, while the */
|
| + /* real meaning of bit 8 (vertical LCD subpixels) stays */
|
| + /* undocumented. The same mistake can be found in Greg Hitchcock's */
|
| + /* whitepaper. */
|
| + /* */
|
| static void
|
| - Ins_GETINFO( INS_ARG )
|
| + Ins_GETINFO( TT_ExecContext exc,
|
| + FT_Long* args )
|
| {
|
| FT_Long K;
|
|
|
| @@ -7744,13 +7305,20 @@
|
| /* Selector Bit: 0 */
|
| /* Return Bit(s): 0-7 */
|
| /* */
|
| - if ( SUBPIXEL_HINTING &&
|
| - ( args[0] & 1 ) != 0 &&
|
| - CUR.ignore_x_mode )
|
| + if ( SUBPIXEL_HINTING &&
|
| + ( args[0] & 1 ) != 0 &&
|
| + exc->subpixel_hinting )
|
| {
|
| - K = CUR.rasterizer_version;
|
| - FT_TRACE7(( "Setting rasterizer version %d\n",
|
| - CUR.rasterizer_version ));
|
| + if ( exc->ignore_x_mode )
|
| + {
|
| + /* if in ClearType backwards compatibility mode, */
|
| + /* we sometimes change the TrueType version dynamically */
|
| + K = exc->rasterizer_version;
|
| + FT_TRACE6(( "Setting rasterizer version %d\n",
|
| + exc->rasterizer_version ));
|
| + }
|
| + else
|
| + K = TT_INTERPRETER_VERSION_38;
|
| }
|
| else
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| @@ -7762,7 +7330,7 @@
|
| /* Selector Bit: 1 */
|
| /* Return Bit(s): 8 */
|
| /* */
|
| - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
|
| + if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
|
| K |= 0x80;
|
|
|
| /********************************/
|
| @@ -7770,7 +7338,7 @@
|
| /* Selector Bit: 2 */
|
| /* Return Bit(s): 9 */
|
| /* */
|
| - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
|
| + if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
|
| K |= 1 << 8;
|
|
|
| /********************************/
|
| @@ -7778,24 +7346,23 @@
|
| /* Selector Bit: 5 */
|
| /* Return Bit(s): 12 */
|
| /* */
|
| - if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
|
| + if ( ( args[0] & 32 ) != 0 && exc->grayscale )
|
| K |= 1 << 12;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| - if ( SUBPIXEL_HINTING &&
|
| - CUR.ignore_x_mode &&
|
| - CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
|
| + if ( SUBPIXEL_HINTING &&
|
| + exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
|
| {
|
|
|
| - if ( CUR.rasterizer_version >= 37 )
|
| + if ( exc->rasterizer_version >= 37 )
|
| {
|
| /********************************/
|
| /* HINTING FOR SUBPIXEL */
|
| /* Selector Bit: 6 */
|
| /* Return Bit(s): 13 */
|
| /* */
|
| - if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
|
| + if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
|
| K |= 1 << 13;
|
|
|
| /********************************/
|
| @@ -7804,16 +7371,16 @@
|
| /* Return Bit(s): 14 */
|
| /* */
|
| /* Functionality still needs to be added */
|
| - if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
|
| + if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
|
| K |= 1 << 14;
|
|
|
| /********************************/
|
| - /* SYMMETRICAL SMOOTHING */
|
| + /* VERTICAL LCD SUBPIXELS? */
|
| /* Selector Bit: 8 */
|
| /* Return Bit(s): 15 */
|
| /* */
|
| /* Functionality still needs to be added */
|
| - if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
|
| + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
|
| K |= 1 << 15;
|
|
|
| /********************************/
|
| @@ -7822,10 +7389,10 @@
|
| /* Return Bit(s): 16 */
|
| /* */
|
| /* Functionality still needs to be added */
|
| - if ( ( args[0] & 512 ) != 0 && CUR.bgr )
|
| + if ( ( args[0] & 512 ) != 0 && exc->bgr )
|
| K |= 1 << 16;
|
|
|
| - if ( CUR.rasterizer_version >= 38 )
|
| + if ( exc->rasterizer_version >= 38 )
|
| {
|
| /********************************/
|
| /* SUBPIXEL POSITIONED? */
|
| @@ -7833,8 +7400,26 @@
|
| /* Return Bit(s): 17 */
|
| /* */
|
| /* Functionality still needs to be added */
|
| - if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
|
| + if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
|
| K |= 1 << 17;
|
| +
|
| + /********************************/
|
| + /* SYMMETRICAL SMOOTHING */
|
| + /* Selector Bit: 11 */
|
| + /* Return Bit(s): 18 */
|
| + /* */
|
| + /* Functionality still needs to be added */
|
| + if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
|
| + K |= 1 << 18;
|
| +
|
| + /********************************/
|
| + /* GRAY CLEARTYPE */
|
| + /* Selector Bit: 12 */
|
| + /* Return Bit(s): 19 */
|
| + /* */
|
| + /* Functionality still needs to be added */
|
| + if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
|
| + K |= 1 << 19;
|
| }
|
| }
|
| }
|
| @@ -7846,331 +7431,43 @@
|
|
|
|
|
| static void
|
| - Ins_UNKNOWN( INS_ARG )
|
| + Ins_UNKNOWN( TT_ExecContext exc )
|
| {
|
| - TT_DefRecord* def = CUR.IDefs;
|
| - TT_DefRecord* limit = def + CUR.numIDefs;
|
| -
|
| - FT_UNUSED_ARG;
|
| + TT_DefRecord* def = exc->IDefs;
|
| + TT_DefRecord* limit = def + exc->numIDefs;
|
|
|
|
|
| for ( ; def < limit; def++ )
|
| {
|
| - if ( (FT_Byte)def->opc == CUR.opcode && def->active )
|
| + if ( (FT_Byte)def->opc == exc->opcode && def->active )
|
| {
|
| TT_CallRec* call;
|
|
|
|
|
| - if ( CUR.callTop >= CUR.callSize )
|
| + if ( exc->callTop >= exc->callSize )
|
| {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| return;
|
| }
|
|
|
| - call = CUR.callStack + CUR.callTop++;
|
| + call = exc->callStack + exc->callTop++;
|
|
|
| - call->Caller_Range = CUR.curRange;
|
| - call->Caller_IP = CUR.IP + 1;
|
| + call->Caller_Range = exc->curRange;
|
| + call->Caller_IP = exc->IP + 1;
|
| call->Cur_Count = 1;
|
| call->Def = def;
|
|
|
| - INS_Goto_CodeRange( def->range, def->start );
|
| + Ins_Goto_CodeRange( exc, def->range, def->start );
|
|
|
| - CUR.step_ins = FALSE;
|
| + exc->step_ins = FALSE;
|
| return;
|
| }
|
| }
|
|
|
| - CUR.error = FT_THROW( Invalid_Opcode );
|
| + exc->error = FT_THROW( Invalid_Opcode );
|
| }
|
|
|
|
|
| -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
|
| -
|
| -
|
| - static
|
| - TInstruction_Function Instruct_Dispatch[256] =
|
| - {
|
| - /* Opcodes are gathered in groups of 16. */
|
| - /* Please keep the spaces as they are. */
|
| -
|
| - /* SVTCA y */ Ins_SVTCA,
|
| - /* SVTCA x */ Ins_SVTCA,
|
| - /* SPvTCA y */ Ins_SPVTCA,
|
| - /* SPvTCA x */ Ins_SPVTCA,
|
| - /* SFvTCA y */ Ins_SFVTCA,
|
| - /* SFvTCA x */ Ins_SFVTCA,
|
| - /* SPvTL // */ Ins_SPVTL,
|
| - /* SPvTL + */ Ins_SPVTL,
|
| - /* SFvTL // */ Ins_SFVTL,
|
| - /* SFvTL + */ Ins_SFVTL,
|
| - /* SPvFS */ Ins_SPVFS,
|
| - /* SFvFS */ Ins_SFVFS,
|
| - /* GPV */ Ins_GPV,
|
| - /* GFV */ Ins_GFV,
|
| - /* SFvTPv */ Ins_SFVTPV,
|
| - /* ISECT */ Ins_ISECT,
|
| -
|
| - /* SRP0 */ Ins_SRP0,
|
| - /* SRP1 */ Ins_SRP1,
|
| - /* SRP2 */ Ins_SRP2,
|
| - /* SZP0 */ Ins_SZP0,
|
| - /* SZP1 */ Ins_SZP1,
|
| - /* SZP2 */ Ins_SZP2,
|
| - /* SZPS */ Ins_SZPS,
|
| - /* SLOOP */ Ins_SLOOP,
|
| - /* RTG */ Ins_RTG,
|
| - /* RTHG */ Ins_RTHG,
|
| - /* SMD */ Ins_SMD,
|
| - /* ELSE */ Ins_ELSE,
|
| - /* JMPR */ Ins_JMPR,
|
| - /* SCvTCi */ Ins_SCVTCI,
|
| - /* SSwCi */ Ins_SSWCI,
|
| - /* SSW */ Ins_SSW,
|
| -
|
| - /* DUP */ Ins_DUP,
|
| - /* POP */ Ins_POP,
|
| - /* CLEAR */ Ins_CLEAR,
|
| - /* SWAP */ Ins_SWAP,
|
| - /* DEPTH */ Ins_DEPTH,
|
| - /* CINDEX */ Ins_CINDEX,
|
| - /* MINDEX */ Ins_MINDEX,
|
| - /* AlignPTS */ Ins_ALIGNPTS,
|
| - /* INS_0x28 */ Ins_UNKNOWN,
|
| - /* UTP */ Ins_UTP,
|
| - /* LOOPCALL */ Ins_LOOPCALL,
|
| - /* CALL */ Ins_CALL,
|
| - /* FDEF */ Ins_FDEF,
|
| - /* ENDF */ Ins_ENDF,
|
| - /* MDAP[0] */ Ins_MDAP,
|
| - /* MDAP[1] */ Ins_MDAP,
|
| -
|
| - /* IUP[0] */ Ins_IUP,
|
| - /* IUP[1] */ Ins_IUP,
|
| - /* SHP[0] */ Ins_SHP,
|
| - /* SHP[1] */ Ins_SHP,
|
| - /* SHC[0] */ Ins_SHC,
|
| - /* SHC[1] */ Ins_SHC,
|
| - /* SHZ[0] */ Ins_SHZ,
|
| - /* SHZ[1] */ Ins_SHZ,
|
| - /* SHPIX */ Ins_SHPIX,
|
| - /* IP */ Ins_IP,
|
| - /* MSIRP[0] */ Ins_MSIRP,
|
| - /* MSIRP[1] */ Ins_MSIRP,
|
| - /* AlignRP */ Ins_ALIGNRP,
|
| - /* RTDG */ Ins_RTDG,
|
| - /* MIAP[0] */ Ins_MIAP,
|
| - /* MIAP[1] */ Ins_MIAP,
|
| -
|
| - /* NPushB */ Ins_NPUSHB,
|
| - /* NPushW */ Ins_NPUSHW,
|
| - /* WS */ Ins_WS,
|
| - /* RS */ Ins_RS,
|
| - /* WCvtP */ Ins_WCVTP,
|
| - /* RCvt */ Ins_RCVT,
|
| - /* GC[0] */ Ins_GC,
|
| - /* GC[1] */ Ins_GC,
|
| - /* SCFS */ Ins_SCFS,
|
| - /* MD[0] */ Ins_MD,
|
| - /* MD[1] */ Ins_MD,
|
| - /* MPPEM */ Ins_MPPEM,
|
| - /* MPS */ Ins_MPS,
|
| - /* FlipON */ Ins_FLIPON,
|
| - /* FlipOFF */ Ins_FLIPOFF,
|
| - /* DEBUG */ Ins_DEBUG,
|
| -
|
| - /* LT */ Ins_LT,
|
| - /* LTEQ */ Ins_LTEQ,
|
| - /* GT */ Ins_GT,
|
| - /* GTEQ */ Ins_GTEQ,
|
| - /* EQ */ Ins_EQ,
|
| - /* NEQ */ Ins_NEQ,
|
| - /* ODD */ Ins_ODD,
|
| - /* EVEN */ Ins_EVEN,
|
| - /* IF */ Ins_IF,
|
| - /* EIF */ Ins_EIF,
|
| - /* AND */ Ins_AND,
|
| - /* OR */ Ins_OR,
|
| - /* NOT */ Ins_NOT,
|
| - /* DeltaP1 */ Ins_DELTAP,
|
| - /* SDB */ Ins_SDB,
|
| - /* SDS */ Ins_SDS,
|
| -
|
| - /* ADD */ Ins_ADD,
|
| - /* SUB */ Ins_SUB,
|
| - /* DIV */ Ins_DIV,
|
| - /* MUL */ Ins_MUL,
|
| - /* ABS */ Ins_ABS,
|
| - /* NEG */ Ins_NEG,
|
| - /* FLOOR */ Ins_FLOOR,
|
| - /* CEILING */ Ins_CEILING,
|
| - /* ROUND[0] */ Ins_ROUND,
|
| - /* ROUND[1] */ Ins_ROUND,
|
| - /* ROUND[2] */ Ins_ROUND,
|
| - /* ROUND[3] */ Ins_ROUND,
|
| - /* NROUND[0] */ Ins_NROUND,
|
| - /* NROUND[1] */ Ins_NROUND,
|
| - /* NROUND[2] */ Ins_NROUND,
|
| - /* NROUND[3] */ Ins_NROUND,
|
| -
|
| - /* WCvtF */ Ins_WCVTF,
|
| - /* DeltaP2 */ Ins_DELTAP,
|
| - /* DeltaP3 */ Ins_DELTAP,
|
| - /* DeltaCn[0] */ Ins_DELTAC,
|
| - /* DeltaCn[1] */ Ins_DELTAC,
|
| - /* DeltaCn[2] */ Ins_DELTAC,
|
| - /* SROUND */ Ins_SROUND,
|
| - /* S45Round */ Ins_S45ROUND,
|
| - /* JROT */ Ins_JROT,
|
| - /* JROF */ Ins_JROF,
|
| - /* ROFF */ Ins_ROFF,
|
| - /* INS_0x7B */ Ins_UNKNOWN,
|
| - /* RUTG */ Ins_RUTG,
|
| - /* RDTG */ Ins_RDTG,
|
| - /* SANGW */ Ins_SANGW,
|
| - /* AA */ Ins_AA,
|
| -
|
| - /* FlipPT */ Ins_FLIPPT,
|
| - /* FlipRgON */ Ins_FLIPRGON,
|
| - /* FlipRgOFF */ Ins_FLIPRGOFF,
|
| - /* INS_0x83 */ Ins_UNKNOWN,
|
| - /* INS_0x84 */ Ins_UNKNOWN,
|
| - /* ScanCTRL */ Ins_SCANCTRL,
|
| - /* SDPVTL[0] */ Ins_SDPVTL,
|
| - /* SDPVTL[1] */ Ins_SDPVTL,
|
| - /* GetINFO */ Ins_GETINFO,
|
| - /* IDEF */ Ins_IDEF,
|
| - /* ROLL */ Ins_ROLL,
|
| - /* MAX */ Ins_MAX,
|
| - /* MIN */ Ins_MIN,
|
| - /* ScanTYPE */ Ins_SCANTYPE,
|
| - /* InstCTRL */ Ins_INSTCTRL,
|
| - /* INS_0x8F */ Ins_UNKNOWN,
|
| -
|
| - /* INS_0x90 */ Ins_UNKNOWN,
|
| - /* INS_0x91 */ Ins_UNKNOWN,
|
| - /* INS_0x92 */ Ins_UNKNOWN,
|
| - /* INS_0x93 */ Ins_UNKNOWN,
|
| - /* INS_0x94 */ Ins_UNKNOWN,
|
| - /* INS_0x95 */ Ins_UNKNOWN,
|
| - /* INS_0x96 */ Ins_UNKNOWN,
|
| - /* INS_0x97 */ Ins_UNKNOWN,
|
| - /* INS_0x98 */ Ins_UNKNOWN,
|
| - /* INS_0x99 */ Ins_UNKNOWN,
|
| - /* INS_0x9A */ Ins_UNKNOWN,
|
| - /* INS_0x9B */ Ins_UNKNOWN,
|
| - /* INS_0x9C */ Ins_UNKNOWN,
|
| - /* INS_0x9D */ Ins_UNKNOWN,
|
| - /* INS_0x9E */ Ins_UNKNOWN,
|
| - /* INS_0x9F */ Ins_UNKNOWN,
|
| -
|
| - /* INS_0xA0 */ Ins_UNKNOWN,
|
| - /* INS_0xA1 */ Ins_UNKNOWN,
|
| - /* INS_0xA2 */ Ins_UNKNOWN,
|
| - /* INS_0xA3 */ Ins_UNKNOWN,
|
| - /* INS_0xA4 */ Ins_UNKNOWN,
|
| - /* INS_0xA5 */ Ins_UNKNOWN,
|
| - /* INS_0xA6 */ Ins_UNKNOWN,
|
| - /* INS_0xA7 */ Ins_UNKNOWN,
|
| - /* INS_0xA8 */ Ins_UNKNOWN,
|
| - /* INS_0xA9 */ Ins_UNKNOWN,
|
| - /* INS_0xAA */ Ins_UNKNOWN,
|
| - /* INS_0xAB */ Ins_UNKNOWN,
|
| - /* INS_0xAC */ Ins_UNKNOWN,
|
| - /* INS_0xAD */ Ins_UNKNOWN,
|
| - /* INS_0xAE */ Ins_UNKNOWN,
|
| - /* INS_0xAF */ Ins_UNKNOWN,
|
| -
|
| - /* PushB[0] */ Ins_PUSHB,
|
| - /* PushB[1] */ Ins_PUSHB,
|
| - /* PushB[2] */ Ins_PUSHB,
|
| - /* PushB[3] */ Ins_PUSHB,
|
| - /* PushB[4] */ Ins_PUSHB,
|
| - /* PushB[5] */ Ins_PUSHB,
|
| - /* PushB[6] */ Ins_PUSHB,
|
| - /* PushB[7] */ Ins_PUSHB,
|
| - /* PushW[0] */ Ins_PUSHW,
|
| - /* PushW[1] */ Ins_PUSHW,
|
| - /* PushW[2] */ Ins_PUSHW,
|
| - /* PushW[3] */ Ins_PUSHW,
|
| - /* PushW[4] */ Ins_PUSHW,
|
| - /* PushW[5] */ Ins_PUSHW,
|
| - /* PushW[6] */ Ins_PUSHW,
|
| - /* PushW[7] */ Ins_PUSHW,
|
| -
|
| - /* MDRP[00] */ Ins_MDRP,
|
| - /* MDRP[01] */ Ins_MDRP,
|
| - /* MDRP[02] */ Ins_MDRP,
|
| - /* MDRP[03] */ Ins_MDRP,
|
| - /* MDRP[04] */ Ins_MDRP,
|
| - /* MDRP[05] */ Ins_MDRP,
|
| - /* MDRP[06] */ Ins_MDRP,
|
| - /* MDRP[07] */ Ins_MDRP,
|
| - /* MDRP[08] */ Ins_MDRP,
|
| - /* MDRP[09] */ Ins_MDRP,
|
| - /* MDRP[10] */ Ins_MDRP,
|
| - /* MDRP[11] */ Ins_MDRP,
|
| - /* MDRP[12] */ Ins_MDRP,
|
| - /* MDRP[13] */ Ins_MDRP,
|
| - /* MDRP[14] */ Ins_MDRP,
|
| - /* MDRP[15] */ Ins_MDRP,
|
| -
|
| - /* MDRP[16] */ Ins_MDRP,
|
| - /* MDRP[17] */ Ins_MDRP,
|
| - /* MDRP[18] */ Ins_MDRP,
|
| - /* MDRP[19] */ Ins_MDRP,
|
| - /* MDRP[20] */ Ins_MDRP,
|
| - /* MDRP[21] */ Ins_MDRP,
|
| - /* MDRP[22] */ Ins_MDRP,
|
| - /* MDRP[23] */ Ins_MDRP,
|
| - /* MDRP[24] */ Ins_MDRP,
|
| - /* MDRP[25] */ Ins_MDRP,
|
| - /* MDRP[26] */ Ins_MDRP,
|
| - /* MDRP[27] */ Ins_MDRP,
|
| - /* MDRP[28] */ Ins_MDRP,
|
| - /* MDRP[29] */ Ins_MDRP,
|
| - /* MDRP[30] */ Ins_MDRP,
|
| - /* MDRP[31] */ Ins_MDRP,
|
| -
|
| - /* MIRP[00] */ Ins_MIRP,
|
| - /* MIRP[01] */ Ins_MIRP,
|
| - /* MIRP[02] */ Ins_MIRP,
|
| - /* MIRP[03] */ Ins_MIRP,
|
| - /* MIRP[04] */ Ins_MIRP,
|
| - /* MIRP[05] */ Ins_MIRP,
|
| - /* MIRP[06] */ Ins_MIRP,
|
| - /* MIRP[07] */ Ins_MIRP,
|
| - /* MIRP[08] */ Ins_MIRP,
|
| - /* MIRP[09] */ Ins_MIRP,
|
| - /* MIRP[10] */ Ins_MIRP,
|
| - /* MIRP[11] */ Ins_MIRP,
|
| - /* MIRP[12] */ Ins_MIRP,
|
| - /* MIRP[13] */ Ins_MIRP,
|
| - /* MIRP[14] */ Ins_MIRP,
|
| - /* MIRP[15] */ Ins_MIRP,
|
| -
|
| - /* MIRP[16] */ Ins_MIRP,
|
| - /* MIRP[17] */ Ins_MIRP,
|
| - /* MIRP[18] */ Ins_MIRP,
|
| - /* MIRP[19] */ Ins_MIRP,
|
| - /* MIRP[20] */ Ins_MIRP,
|
| - /* MIRP[21] */ Ins_MIRP,
|
| - /* MIRP[22] */ Ins_MIRP,
|
| - /* MIRP[23] */ Ins_MIRP,
|
| - /* MIRP[24] */ Ins_MIRP,
|
| - /* MIRP[25] */ Ins_MIRP,
|
| - /* MIRP[26] */ Ins_MIRP,
|
| - /* MIRP[27] */ Ins_MIRP,
|
| - /* MIRP[28] */ Ins_MIRP,
|
| - /* MIRP[29] */ Ins_MIRP,
|
| - /* MIRP[30] */ Ins_MIRP,
|
| - /* MIRP[31] */ Ins_MIRP
|
| - };
|
| -
|
| -
|
| -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
|
| -
|
| -
|
| /*************************************************************************/
|
| /* */
|
| /* RUN */
|
| @@ -8198,8 +7495,6 @@
|
| /* */
|
| /* THIS IS THE INTERPRETER'S MAIN LOOP. */
|
| /* */
|
| - /* Instructions appear in the specification's order. */
|
| - /* */
|
| /*************************************************************************/
|
|
|
|
|
| @@ -8225,90 +7520,100 @@
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
|
|
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
|
| - if ( !exc )
|
| - return FT_THROW( Invalid_Argument );
|
| -
|
| - cur = *exc;
|
| -#endif
|
| -
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| - CUR.iup_called = FALSE;
|
| + exc->iup_called = FALSE;
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| /* set PPEM and CVT functions */
|
| - CUR.tt_metrics.ratio = 0;
|
| - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
|
| + exc->tt_metrics.ratio = 0;
|
| + if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
|
| {
|
| /* non-square pixels, use the stretched routines */
|
| - CUR.func_cur_ppem = Current_Ppem_Stretched;
|
| - CUR.func_read_cvt = Read_CVT_Stretched;
|
| - CUR.func_write_cvt = Write_CVT_Stretched;
|
| - CUR.func_move_cvt = Move_CVT_Stretched;
|
| + exc->func_cur_ppem = Current_Ppem_Stretched;
|
| + exc->func_read_cvt = Read_CVT_Stretched;
|
| + exc->func_write_cvt = Write_CVT_Stretched;
|
| + exc->func_move_cvt = Move_CVT_Stretched;
|
| }
|
| else
|
| {
|
| /* square pixels, use normal routines */
|
| - CUR.func_cur_ppem = Current_Ppem;
|
| - CUR.func_read_cvt = Read_CVT;
|
| - CUR.func_write_cvt = Write_CVT;
|
| - CUR.func_move_cvt = Move_CVT;
|
| + exc->func_cur_ppem = Current_Ppem;
|
| + exc->func_read_cvt = Read_CVT;
|
| + exc->func_write_cvt = Write_CVT;
|
| + exc->func_move_cvt = Move_CVT;
|
| }
|
|
|
| - COMPUTE_Funcs();
|
| - COMPUTE_Round( (FT_Byte)exc->GS.round_state );
|
| + Compute_Funcs( exc );
|
| + Compute_Round( exc, (FT_Byte)exc->GS.round_state );
|
|
|
| do
|
| {
|
| - CUR.opcode = CUR.code[CUR.IP];
|
| + exc->opcode = exc->code[exc->IP];
|
|
|
| - FT_TRACE7(( " " ));
|
| - FT_TRACE7(( opcode_name[CUR.opcode] ));
|
| - FT_TRACE7(( "\n" ));
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + {
|
| + FT_Long cnt = FT_MIN( 8, exc->top );
|
| + FT_Long n;
|
| +
|
| +
|
| + /* if tracing level is 7, show current code position */
|
| + /* and the first few stack elements also */
|
| + FT_TRACE6(( " " ));
|
| + FT_TRACE7(( "%06d ", exc->IP ));
|
| + FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
|
| + FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
|
| + ? 2
|
| + : 12 - ( *opcode_name[exc->opcode] - '0' ),
|
| + "#" ));
|
| + for ( n = 0; n < cnt; n++ )
|
| + FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
|
| + FT_TRACE6(( "\n" ));
|
| + }
|
| +#endif /* FT_DEBUG_LEVEL_TRACE */
|
|
|
| - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
|
| + if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
|
| {
|
| - if ( CUR.IP + 1 >= CUR.codeSize )
|
| + if ( exc->IP + 1 >= exc->codeSize )
|
| goto LErrorCodeOverflow_;
|
|
|
| - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
|
| + exc->length = 2 - exc->length * exc->code[exc->IP + 1];
|
| }
|
|
|
| - if ( CUR.IP + CUR.length > CUR.codeSize )
|
| + if ( exc->IP + exc->length > exc->codeSize )
|
| goto LErrorCodeOverflow_;
|
|
|
| /* First, let's check for empty stack and overflow */
|
| - CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
|
| + exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
|
|
|
| /* `args' is the top of the stack once arguments have been popped. */
|
| /* One can also interpret it as the index of the last argument. */
|
| - if ( CUR.args < 0 )
|
| + if ( exc->args < 0 )
|
| {
|
| - if ( CUR.pedantic_hinting )
|
| + if ( exc->pedantic_hinting )
|
| {
|
| - CUR.error = FT_THROW( Too_Few_Arguments );
|
| + exc->error = FT_THROW( Too_Few_Arguments );
|
| goto LErrorLabel_;
|
| }
|
|
|
| /* push zeroes onto the stack */
|
| - for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ )
|
| - CUR.stack[i] = 0;
|
| - CUR.args = 0;
|
| + for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
|
| + exc->stack[i] = 0;
|
| + exc->args = 0;
|
| }
|
|
|
| - CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );
|
| + exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
|
|
|
| /* `new_top' is the new top of the stack, after the instruction's */
|
| /* execution. `top' will be set to `new_top' after the `switch' */
|
| /* statement. */
|
| - if ( CUR.new_top > CUR.stackSize )
|
| + if ( exc->new_top > exc->stackSize )
|
| {
|
| - CUR.error = FT_THROW( Stack_Overflow );
|
| + exc->error = FT_THROW( Stack_Overflow );
|
| goto LErrorLabel_;
|
| }
|
|
|
| - CUR.step_ins = TRUE;
|
| - CUR.error = FT_Err_Ok;
|
| + exc->step_ins = TRUE;
|
| + exc->error = FT_Err_Ok;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| @@ -8316,17 +7621,17 @@
|
| {
|
| for ( i = 0; i < opcode_patterns; i++ )
|
| {
|
| - if ( opcode_pointer[i] < opcode_size[i] &&
|
| - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
|
| + if ( opcode_pointer[i] < opcode_size[i] &&
|
| + exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
|
| {
|
| opcode_pointer[i] += 1;
|
|
|
| if ( opcode_pointer[i] == opcode_size[i] )
|
| {
|
| - FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
|
| + FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
|
| i,
|
| - CUR.face->root.family_name,
|
| - CUR.face->root.style_name ));
|
| + exc->face->root.family_name,
|
| + exc->face->root.style_name ));
|
|
|
| switch ( i )
|
| {
|
| @@ -8343,15 +7648,9 @@
|
|
|
| #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
|
|
| -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
|
| -
|
| {
|
| - FT_Long* args = CUR.stack + CUR.args;
|
| - FT_Byte opcode = CUR.opcode;
|
| -
|
| -
|
| -#undef ARRAY_BOUND_ERROR
|
| -#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref
|
| + FT_Long* args = exc->stack + exc->args;
|
| + FT_Byte opcode = exc->opcode;
|
|
|
|
|
| switch ( opcode )
|
| @@ -8362,580 +7661,543 @@
|
| case 0x03: /* SPvTCA x */
|
| case 0x04: /* SFvTCA y */
|
| case 0x05: /* SFvTCA x */
|
| - {
|
| - FT_Short AA, BB;
|
| -
|
| -
|
| - AA = (FT_Short)( ( opcode & 1 ) << 14 );
|
| - BB = (FT_Short)( AA ^ 0x4000 );
|
| -
|
| - if ( opcode < 4 )
|
| - {
|
| - CUR.GS.projVector.x = AA;
|
| - CUR.GS.projVector.y = BB;
|
| -
|
| - CUR.GS.dualVector.x = AA;
|
| - CUR.GS.dualVector.y = BB;
|
| - }
|
| - else
|
| - {
|
| - GUESS_VECTOR( projVector );
|
| - }
|
| -
|
| - if ( ( opcode & 2 ) == 0 )
|
| - {
|
| - CUR.GS.freeVector.x = AA;
|
| - CUR.GS.freeVector.y = BB;
|
| - }
|
| - else
|
| - {
|
| - GUESS_VECTOR( freeVector );
|
| - }
|
| -
|
| - COMPUTE_Funcs();
|
| - }
|
| + Ins_SxyTCA( exc );
|
| break;
|
|
|
| case 0x06: /* SPvTL // */
|
| case 0x07: /* SPvTL + */
|
| - DO_SPVTL
|
| + Ins_SPVTL( exc, args );
|
| break;
|
|
|
| case 0x08: /* SFvTL // */
|
| case 0x09: /* SFvTL + */
|
| - DO_SFVTL
|
| + Ins_SFVTL( exc, args );
|
| break;
|
|
|
| case 0x0A: /* SPvFS */
|
| - DO_SPVFS
|
| + Ins_SPVFS( exc, args );
|
| break;
|
|
|
| case 0x0B: /* SFvFS */
|
| - DO_SFVFS
|
| + Ins_SFVFS( exc, args );
|
| break;
|
|
|
| - case 0x0C: /* GPV */
|
| - DO_GPV
|
| + case 0x0C: /* GPv */
|
| + Ins_GPV( exc, args );
|
| break;
|
|
|
| - case 0x0D: /* GFV */
|
| - DO_GFV
|
| + case 0x0D: /* GFv */
|
| + Ins_GFV( exc, args );
|
| break;
|
|
|
| case 0x0E: /* SFvTPv */
|
| - DO_SFVTPV
|
| + Ins_SFVTPV( exc );
|
| break;
|
|
|
| case 0x0F: /* ISECT */
|
| - Ins_ISECT( EXEC_ARG_ args );
|
| + Ins_ISECT( exc, args );
|
| break;
|
|
|
| case 0x10: /* SRP0 */
|
| - DO_SRP0
|
| + Ins_SRP0( exc, args );
|
| break;
|
|
|
| case 0x11: /* SRP1 */
|
| - DO_SRP1
|
| + Ins_SRP1( exc, args );
|
| break;
|
|
|
| case 0x12: /* SRP2 */
|
| - DO_SRP2
|
| + Ins_SRP2( exc, args );
|
| break;
|
|
|
| case 0x13: /* SZP0 */
|
| - Ins_SZP0( EXEC_ARG_ args );
|
| + Ins_SZP0( exc, args );
|
| break;
|
|
|
| case 0x14: /* SZP1 */
|
| - Ins_SZP1( EXEC_ARG_ args );
|
| + Ins_SZP1( exc, args );
|
| break;
|
|
|
| case 0x15: /* SZP2 */
|
| - Ins_SZP2( EXEC_ARG_ args );
|
| + Ins_SZP2( exc, args );
|
| break;
|
|
|
| case 0x16: /* SZPS */
|
| - Ins_SZPS( EXEC_ARG_ args );
|
| + Ins_SZPS( exc, args );
|
| break;
|
|
|
| case 0x17: /* SLOOP */
|
| - DO_SLOOP
|
| + Ins_SLOOP( exc, args );
|
| break;
|
|
|
| case 0x18: /* RTG */
|
| - DO_RTG
|
| + Ins_RTG( exc );
|
| break;
|
|
|
| case 0x19: /* RTHG */
|
| - DO_RTHG
|
| + Ins_RTHG( exc );
|
| break;
|
|
|
| case 0x1A: /* SMD */
|
| - DO_SMD
|
| + Ins_SMD( exc, args );
|
| break;
|
|
|
| case 0x1B: /* ELSE */
|
| - Ins_ELSE( EXEC_ARG_ args );
|
| + Ins_ELSE( exc );
|
| break;
|
|
|
| case 0x1C: /* JMPR */
|
| - DO_JMPR
|
| + Ins_JMPR( exc, args );
|
| break;
|
|
|
| case 0x1D: /* SCVTCI */
|
| - DO_SCVTCI
|
| + Ins_SCVTCI( exc, args );
|
| break;
|
|
|
| case 0x1E: /* SSWCI */
|
| - DO_SSWCI
|
| + Ins_SSWCI( exc, args );
|
| break;
|
|
|
| case 0x1F: /* SSW */
|
| - DO_SSW
|
| + Ins_SSW( exc, args );
|
| break;
|
|
|
| case 0x20: /* DUP */
|
| - DO_DUP
|
| + Ins_DUP( args );
|
| break;
|
|
|
| case 0x21: /* POP */
|
| - /* nothing :-) */
|
| + Ins_POP();
|
| break;
|
|
|
| case 0x22: /* CLEAR */
|
| - DO_CLEAR
|
| + Ins_CLEAR( exc );
|
| break;
|
|
|
| case 0x23: /* SWAP */
|
| - DO_SWAP
|
| + Ins_SWAP( args );
|
| break;
|
|
|
| case 0x24: /* DEPTH */
|
| - DO_DEPTH
|
| + Ins_DEPTH( exc, args );
|
| break;
|
|
|
| case 0x25: /* CINDEX */
|
| - DO_CINDEX
|
| + Ins_CINDEX( exc, args );
|
| break;
|
|
|
| case 0x26: /* MINDEX */
|
| - Ins_MINDEX( EXEC_ARG_ args );
|
| + Ins_MINDEX( exc, args );
|
| break;
|
|
|
| case 0x27: /* ALIGNPTS */
|
| - Ins_ALIGNPTS( EXEC_ARG_ args );
|
| + Ins_ALIGNPTS( exc, args );
|
| break;
|
|
|
| case 0x28: /* ???? */
|
| - Ins_UNKNOWN( EXEC_ARG_ args );
|
| + Ins_UNKNOWN( exc );
|
| break;
|
|
|
| case 0x29: /* UTP */
|
| - Ins_UTP( EXEC_ARG_ args );
|
| + Ins_UTP( exc, args );
|
| break;
|
|
|
| case 0x2A: /* LOOPCALL */
|
| - Ins_LOOPCALL( EXEC_ARG_ args );
|
| + Ins_LOOPCALL( exc, args );
|
| break;
|
|
|
| case 0x2B: /* CALL */
|
| - Ins_CALL( EXEC_ARG_ args );
|
| + Ins_CALL( exc, args );
|
| break;
|
|
|
| case 0x2C: /* FDEF */
|
| - Ins_FDEF( EXEC_ARG_ args );
|
| + Ins_FDEF( exc, args );
|
| break;
|
|
|
| case 0x2D: /* ENDF */
|
| - Ins_ENDF( EXEC_ARG_ args );
|
| + Ins_ENDF( exc );
|
| break;
|
|
|
| case 0x2E: /* MDAP */
|
| case 0x2F: /* MDAP */
|
| - Ins_MDAP( EXEC_ARG_ args );
|
| + Ins_MDAP( exc, args );
|
| break;
|
|
|
| case 0x30: /* IUP */
|
| case 0x31: /* IUP */
|
| - Ins_IUP( EXEC_ARG_ args );
|
| + Ins_IUP( exc );
|
| break;
|
|
|
| case 0x32: /* SHP */
|
| case 0x33: /* SHP */
|
| - Ins_SHP( EXEC_ARG_ args );
|
| + Ins_SHP( exc );
|
| break;
|
|
|
| case 0x34: /* SHC */
|
| case 0x35: /* SHC */
|
| - Ins_SHC( EXEC_ARG_ args );
|
| + Ins_SHC( exc, args );
|
| break;
|
|
|
| case 0x36: /* SHZ */
|
| case 0x37: /* SHZ */
|
| - Ins_SHZ( EXEC_ARG_ args );
|
| + Ins_SHZ( exc, args );
|
| break;
|
|
|
| case 0x38: /* SHPIX */
|
| - Ins_SHPIX( EXEC_ARG_ args );
|
| + Ins_SHPIX( exc, args );
|
| break;
|
|
|
| case 0x39: /* IP */
|
| - Ins_IP( EXEC_ARG_ args );
|
| + Ins_IP( exc );
|
| break;
|
|
|
| case 0x3A: /* MSIRP */
|
| case 0x3B: /* MSIRP */
|
| - Ins_MSIRP( EXEC_ARG_ args );
|
| + Ins_MSIRP( exc, args );
|
| break;
|
|
|
| case 0x3C: /* AlignRP */
|
| - Ins_ALIGNRP( EXEC_ARG_ args );
|
| + Ins_ALIGNRP( exc );
|
| break;
|
|
|
| case 0x3D: /* RTDG */
|
| - DO_RTDG
|
| + Ins_RTDG( exc );
|
| break;
|
|
|
| case 0x3E: /* MIAP */
|
| case 0x3F: /* MIAP */
|
| - Ins_MIAP( EXEC_ARG_ args );
|
| + Ins_MIAP( exc, args );
|
| break;
|
|
|
| case 0x40: /* NPUSHB */
|
| - Ins_NPUSHB( EXEC_ARG_ args );
|
| + Ins_NPUSHB( exc, args );
|
| break;
|
|
|
| case 0x41: /* NPUSHW */
|
| - Ins_NPUSHW( EXEC_ARG_ args );
|
| + Ins_NPUSHW( exc, args );
|
| break;
|
|
|
| case 0x42: /* WS */
|
| - DO_WS
|
| - break;
|
| -
|
| - Set_Invalid_Ref:
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + Ins_WS( exc, args );
|
| break;
|
|
|
| case 0x43: /* RS */
|
| - DO_RS
|
| + Ins_RS( exc, args );
|
| break;
|
|
|
| case 0x44: /* WCVTP */
|
| - DO_WCVTP
|
| + Ins_WCVTP( exc, args );
|
| break;
|
|
|
| case 0x45: /* RCVT */
|
| - DO_RCVT
|
| + Ins_RCVT( exc, args );
|
| break;
|
|
|
| case 0x46: /* GC */
|
| case 0x47: /* GC */
|
| - Ins_GC( EXEC_ARG_ args );
|
| + Ins_GC( exc, args );
|
| break;
|
|
|
| case 0x48: /* SCFS */
|
| - Ins_SCFS( EXEC_ARG_ args );
|
| + Ins_SCFS( exc, args );
|
| break;
|
|
|
| case 0x49: /* MD */
|
| case 0x4A: /* MD */
|
| - Ins_MD( EXEC_ARG_ args );
|
| + Ins_MD( exc, args );
|
| break;
|
|
|
| case 0x4B: /* MPPEM */
|
| - DO_MPPEM
|
| + Ins_MPPEM( exc, args );
|
| break;
|
|
|
| case 0x4C: /* MPS */
|
| - DO_MPS
|
| + Ins_MPS( exc, args );
|
| break;
|
|
|
| case 0x4D: /* FLIPON */
|
| - DO_FLIPON
|
| + Ins_FLIPON( exc );
|
| break;
|
|
|
| case 0x4E: /* FLIPOFF */
|
| - DO_FLIPOFF
|
| + Ins_FLIPOFF( exc );
|
| break;
|
|
|
| case 0x4F: /* DEBUG */
|
| - DO_DEBUG
|
| + Ins_DEBUG( exc );
|
| break;
|
|
|
| case 0x50: /* LT */
|
| - DO_LT
|
| + Ins_LT( args );
|
| break;
|
|
|
| case 0x51: /* LTEQ */
|
| - DO_LTEQ
|
| + Ins_LTEQ( args );
|
| break;
|
|
|
| case 0x52: /* GT */
|
| - DO_GT
|
| + Ins_GT( args );
|
| break;
|
|
|
| case 0x53: /* GTEQ */
|
| - DO_GTEQ
|
| + Ins_GTEQ( args );
|
| break;
|
|
|
| case 0x54: /* EQ */
|
| - DO_EQ
|
| + Ins_EQ( args );
|
| break;
|
|
|
| case 0x55: /* NEQ */
|
| - DO_NEQ
|
| + Ins_NEQ( args );
|
| break;
|
|
|
| case 0x56: /* ODD */
|
| - DO_ODD
|
| + Ins_ODD( exc, args );
|
| break;
|
|
|
| case 0x57: /* EVEN */
|
| - DO_EVEN
|
| + Ins_EVEN( exc, args );
|
| break;
|
|
|
| case 0x58: /* IF */
|
| - Ins_IF( EXEC_ARG_ args );
|
| + Ins_IF( exc, args );
|
| break;
|
|
|
| case 0x59: /* EIF */
|
| - /* do nothing */
|
| + Ins_EIF();
|
| break;
|
|
|
| case 0x5A: /* AND */
|
| - DO_AND
|
| + Ins_AND( args );
|
| break;
|
|
|
| case 0x5B: /* OR */
|
| - DO_OR
|
| + Ins_OR( args );
|
| break;
|
|
|
| case 0x5C: /* NOT */
|
| - DO_NOT
|
| + Ins_NOT( args );
|
| break;
|
|
|
| case 0x5D: /* DELTAP1 */
|
| - Ins_DELTAP( EXEC_ARG_ args );
|
| + Ins_DELTAP( exc, args );
|
| break;
|
|
|
| case 0x5E: /* SDB */
|
| - DO_SDB
|
| + Ins_SDB( exc, args );
|
| break;
|
|
|
| case 0x5F: /* SDS */
|
| - DO_SDS
|
| + Ins_SDS( exc, args );
|
| break;
|
|
|
| case 0x60: /* ADD */
|
| - DO_ADD
|
| + Ins_ADD( args );
|
| break;
|
|
|
| case 0x61: /* SUB */
|
| - DO_SUB
|
| + Ins_SUB( args );
|
| break;
|
|
|
| case 0x62: /* DIV */
|
| - DO_DIV
|
| + Ins_DIV( exc, args );
|
| break;
|
|
|
| case 0x63: /* MUL */
|
| - DO_MUL
|
| + Ins_MUL( args );
|
| break;
|
|
|
| case 0x64: /* ABS */
|
| - DO_ABS
|
| + Ins_ABS( args );
|
| break;
|
|
|
| case 0x65: /* NEG */
|
| - DO_NEG
|
| + Ins_NEG( args );
|
| break;
|
|
|
| case 0x66: /* FLOOR */
|
| - DO_FLOOR
|
| + Ins_FLOOR( args );
|
| break;
|
|
|
| case 0x67: /* CEILING */
|
| - DO_CEILING
|
| + Ins_CEILING( args );
|
| break;
|
|
|
| case 0x68: /* ROUND */
|
| case 0x69: /* ROUND */
|
| case 0x6A: /* ROUND */
|
| case 0x6B: /* ROUND */
|
| - DO_ROUND
|
| + Ins_ROUND( exc, args );
|
| break;
|
|
|
| case 0x6C: /* NROUND */
|
| case 0x6D: /* NROUND */
|
| case 0x6E: /* NRRUND */
|
| case 0x6F: /* NROUND */
|
| - DO_NROUND
|
| + Ins_NROUND( exc, args );
|
| break;
|
|
|
| case 0x70: /* WCVTF */
|
| - DO_WCVTF
|
| + Ins_WCVTF( exc, args );
|
| break;
|
|
|
| case 0x71: /* DELTAP2 */
|
| case 0x72: /* DELTAP3 */
|
| - Ins_DELTAP( EXEC_ARG_ args );
|
| + Ins_DELTAP( exc, args );
|
| break;
|
|
|
| case 0x73: /* DELTAC0 */
|
| case 0x74: /* DELTAC1 */
|
| case 0x75: /* DELTAC2 */
|
| - Ins_DELTAC( EXEC_ARG_ args );
|
| + Ins_DELTAC( exc, args );
|
| break;
|
|
|
| case 0x76: /* SROUND */
|
| - DO_SROUND
|
| + Ins_SROUND( exc, args );
|
| break;
|
|
|
| case 0x77: /* S45Round */
|
| - DO_S45ROUND
|
| + Ins_S45ROUND( exc, args );
|
| break;
|
|
|
| case 0x78: /* JROT */
|
| - DO_JROT
|
| + Ins_JROT( exc, args );
|
| break;
|
|
|
| case 0x79: /* JROF */
|
| - DO_JROF
|
| + Ins_JROF( exc, args );
|
| break;
|
|
|
| case 0x7A: /* ROFF */
|
| - DO_ROFF
|
| + Ins_ROFF( exc );
|
| break;
|
|
|
| case 0x7B: /* ???? */
|
| - Ins_UNKNOWN( EXEC_ARG_ args );
|
| + Ins_UNKNOWN( exc );
|
| break;
|
|
|
| case 0x7C: /* RUTG */
|
| - DO_RUTG
|
| + Ins_RUTG( exc );
|
| break;
|
|
|
| case 0x7D: /* RDTG */
|
| - DO_RDTG
|
| + Ins_RDTG( exc );
|
| break;
|
|
|
| case 0x7E: /* SANGW */
|
| - case 0x7F: /* AA */
|
| - /* nothing - obsolete */
|
| + Ins_SANGW();
|
| + break;
|
| +
|
| + case 0x7F: /* AA */
|
| + Ins_AA();
|
| break;
|
|
|
| case 0x80: /* FLIPPT */
|
| - Ins_FLIPPT( EXEC_ARG_ args );
|
| + Ins_FLIPPT( exc );
|
| break;
|
|
|
| case 0x81: /* FLIPRGON */
|
| - Ins_FLIPRGON( EXEC_ARG_ args );
|
| + Ins_FLIPRGON( exc, args );
|
| break;
|
|
|
| case 0x82: /* FLIPRGOFF */
|
| - Ins_FLIPRGOFF( EXEC_ARG_ args );
|
| + Ins_FLIPRGOFF( exc, args );
|
| break;
|
|
|
| case 0x83: /* UNKNOWN */
|
| case 0x84: /* UNKNOWN */
|
| - Ins_UNKNOWN( EXEC_ARG_ args );
|
| + Ins_UNKNOWN( exc );
|
| break;
|
|
|
| case 0x85: /* SCANCTRL */
|
| - Ins_SCANCTRL( EXEC_ARG_ args );
|
| + Ins_SCANCTRL( exc, args );
|
| break;
|
|
|
| - case 0x86: /* SDPVTL */
|
| - case 0x87: /* SDPVTL */
|
| - Ins_SDPVTL( EXEC_ARG_ args );
|
| + case 0x86: /* SDPvTL */
|
| + case 0x87: /* SDPvTL */
|
| + Ins_SDPVTL( exc, args );
|
| break;
|
|
|
| case 0x88: /* GETINFO */
|
| - Ins_GETINFO( EXEC_ARG_ args );
|
| + Ins_GETINFO( exc, args );
|
| break;
|
|
|
| case 0x89: /* IDEF */
|
| - Ins_IDEF( EXEC_ARG_ args );
|
| + Ins_IDEF( exc, args );
|
| break;
|
|
|
| case 0x8A: /* ROLL */
|
| - Ins_ROLL( EXEC_ARG_ args );
|
| + Ins_ROLL( args );
|
| break;
|
|
|
| case 0x8B: /* MAX */
|
| - DO_MAX
|
| + Ins_MAX( args );
|
| break;
|
|
|
| case 0x8C: /* MIN */
|
| - DO_MIN
|
| + Ins_MIN( args );
|
| break;
|
|
|
| case 0x8D: /* SCANTYPE */
|
| - Ins_SCANTYPE( EXEC_ARG_ args );
|
| + Ins_SCANTYPE( exc, args );
|
| break;
|
|
|
| case 0x8E: /* INSTCTRL */
|
| - Ins_INSTCTRL( EXEC_ARG_ args );
|
| + Ins_INSTCTRL( exc, args );
|
| break;
|
|
|
| case 0x8F:
|
| - Ins_UNKNOWN( EXEC_ARG_ args );
|
| + Ins_UNKNOWN( exc );
|
| break;
|
|
|
| default:
|
| if ( opcode >= 0xE0 )
|
| - Ins_MIRP( EXEC_ARG_ args );
|
| + Ins_MIRP( exc, args );
|
| else if ( opcode >= 0xC0 )
|
| - Ins_MDRP( EXEC_ARG_ args );
|
| + Ins_MDRP( exc, args );
|
| else if ( opcode >= 0xB8 )
|
| - Ins_PUSHW( EXEC_ARG_ args );
|
| + Ins_PUSHW( exc, args );
|
| else if ( opcode >= 0xB0 )
|
| - Ins_PUSHB( EXEC_ARG_ args );
|
| + Ins_PUSHB( exc, args );
|
| else
|
| - Ins_UNKNOWN( EXEC_ARG_ args );
|
| + Ins_UNKNOWN( exc );
|
| }
|
| -
|
| }
|
|
|
| -#else
|
| -
|
| - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
|
| -
|
| -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
|
| -
|
| - if ( CUR.error )
|
| + if ( exc->error )
|
| {
|
| - switch ( CUR.error )
|
| + switch ( exc->error )
|
| {
|
| /* looking for redefined instructions */
|
| case FT_ERR( Invalid_Opcode ):
|
| {
|
| - TT_DefRecord* def = CUR.IDefs;
|
| - TT_DefRecord* limit = def + CUR.numIDefs;
|
| + TT_DefRecord* def = exc->IDefs;
|
| + TT_DefRecord* limit = def + exc->numIDefs;
|
|
|
|
|
| for ( ; def < limit; def++ )
|
| {
|
| - if ( def->active && CUR.opcode == (FT_Byte)def->opc )
|
| + if ( def->active && exc->opcode == (FT_Byte)def->opc )
|
| {
|
| TT_CallRec* callrec;
|
|
|
|
|
| - if ( CUR.callTop >= CUR.callSize )
|
| + if ( exc->callTop >= exc->callSize )
|
| {
|
| - CUR.error = FT_THROW( Invalid_Reference );
|
| + exc->error = FT_THROW( Invalid_Reference );
|
| goto LErrorLabel_;
|
| }
|
|
|
| - callrec = &CUR.callStack[CUR.callTop];
|
| + callrec = &exc->callStack[exc->callTop];
|
|
|
| - callrec->Caller_Range = CUR.curRange;
|
| - callrec->Caller_IP = CUR.IP + 1;
|
| + callrec->Caller_Range = exc->curRange;
|
| + callrec->Caller_IP = exc->IP + 1;
|
| callrec->Cur_Count = 1;
|
| callrec->Def = def;
|
|
|
| - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
|
| + if ( Ins_Goto_CodeRange( exc,
|
| + def->range,
|
| + def->start ) == FAILURE )
|
| goto LErrorLabel_;
|
|
|
| goto LSuiteLabel_;
|
| @@ -8943,7 +8205,7 @@
|
| }
|
| }
|
|
|
| - CUR.error = FT_THROW( Invalid_Opcode );
|
| + exc->error = FT_THROW( Invalid_Opcode );
|
| goto LErrorLabel_;
|
|
|
| #if 0
|
| @@ -8961,10 +8223,10 @@
|
| }
|
| }
|
|
|
| - CUR.top = CUR.new_top;
|
| + exc->top = exc->new_top;
|
|
|
| - if ( CUR.step_ins )
|
| - CUR.IP += CUR.length;
|
| + if ( exc->step_ins )
|
| + exc->IP += exc->length;
|
|
|
| /* increment instruction counter and check if we didn't */
|
| /* run this program for too long (e.g. infinite loops). */
|
| @@ -8972,48 +8234,38 @@
|
| return FT_THROW( Execution_Too_Long );
|
|
|
| LSuiteLabel_:
|
| - if ( CUR.IP >= CUR.codeSize )
|
| + if ( exc->IP >= exc->codeSize )
|
| {
|
| - if ( CUR.callTop > 0 )
|
| + if ( exc->callTop > 0 )
|
| {
|
| - CUR.error = FT_THROW( Code_Overflow );
|
| + exc->error = FT_THROW( Code_Overflow );
|
| goto LErrorLabel_;
|
| }
|
| else
|
| goto LNo_Error_;
|
| }
|
| - } while ( !CUR.instruction_trap );
|
| + } while ( !exc->instruction_trap );
|
|
|
| LNo_Error_:
|
| -
|
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
|
| - *exc = cur;
|
| -#endif
|
| -
|
| return FT_Err_Ok;
|
|
|
| LErrorCodeOverflow_:
|
| - CUR.error = FT_THROW( Code_Overflow );
|
| + exc->error = FT_THROW( Code_Overflow );
|
|
|
| LErrorLabel_:
|
| -
|
| -#ifdef TT_CONFIG_OPTION_STATIC_RASTER
|
| - *exc = cur;
|
| -#endif
|
| -
|
| /* If any errors have occurred, function tables may be broken. */
|
| /* Force a re-execution of `prep' and `fpgm' tables if no */
|
| /* bytecode debugger is run. */
|
| - if ( CUR.error
|
| - && !CUR.instruction_trap
|
| - && CUR.curRange == tt_coderange_glyph )
|
| + if ( exc->error &&
|
| + !exc->instruction_trap &&
|
| + exc->curRange == tt_coderange_glyph )
|
| {
|
| - FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
|
| + FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error ));
|
| exc->size->bytecode_ready = -1;
|
| exc->size->cvt_ready = -1;
|
| }
|
|
|
| - return CUR.error;
|
| + return exc->error;
|
| }
|
|
|
|
|
|
|