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; |
} |