1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ttinterp.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* TrueType bytecode interpreter (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 21*37da2899SCharles.Forsyth #include FT_INTERNAL_CALC_H 22*37da2899SCharles.Forsyth #include FT_TRIGONOMETRY_H 23*37da2899SCharles.Forsyth #include FT_SYSTEM_H 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth #include "ttinterp.h" 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth #include "tterrors.h" 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER 31*37da2899SCharles.Forsyth 32*37da2899SCharles.Forsyth 33*37da2899SCharles.Forsyth #define TT_MULFIX FT_MulFix 34*37da2899SCharles.Forsyth #define TT_MULDIV FT_MulDiv 35*37da2899SCharles.Forsyth #define TT_INT64 FT_Int64 36*37da2899SCharles.Forsyth 37*37da2899SCharles.Forsyth /*************************************************************************/ 38*37da2899SCharles.Forsyth /* */ 39*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 40*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 41*37da2899SCharles.Forsyth /* messages during execution. */ 42*37da2899SCharles.Forsyth /* */ 43*37da2899SCharles.Forsyth #undef FT_COMPONENT 44*37da2899SCharles.Forsyth #define FT_COMPONENT trace_ttinterp 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth #undef NO_APPLE_PATENT 47*37da2899SCharles.Forsyth #define APPLE_THRESHOLD 0x4000000L 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth /*************************************************************************/ 50*37da2899SCharles.Forsyth /* */ 51*37da2899SCharles.Forsyth /* In order to detect infinite loops in the code, we set up a counter */ 52*37da2899SCharles.Forsyth /* within the run loop. A single stroke of interpretation is now */ 53*37da2899SCharles.Forsyth /* limitet to a maximal number of opcodes defined below. */ 54*37da2899SCharles.Forsyth /* */ 55*37da2899SCharles.Forsyth #define MAX_RUNNABLE_OPCODES 1000000L 56*37da2899SCharles.Forsyth 57*37da2899SCharles.Forsyth 58*37da2899SCharles.Forsyth /*************************************************************************/ 59*37da2899SCharles.Forsyth /* */ 60*37da2899SCharles.Forsyth /* There are two kinds of implementations: */ 61*37da2899SCharles.Forsyth /* */ 62*37da2899SCharles.Forsyth /* a. static implementation */ 63*37da2899SCharles.Forsyth /* */ 64*37da2899SCharles.Forsyth /* The current execution context is a static variable, which fields */ 65*37da2899SCharles.Forsyth /* are accessed directly by the interpreter during execution. The */ 66*37da2899SCharles.Forsyth /* context is named `cur'. */ 67*37da2899SCharles.Forsyth /* */ 68*37da2899SCharles.Forsyth /* This version is non-reentrant, of course. */ 69*37da2899SCharles.Forsyth /* */ 70*37da2899SCharles.Forsyth /* b. indirect implementation */ 71*37da2899SCharles.Forsyth /* */ 72*37da2899SCharles.Forsyth /* The current execution context is passed to _each_ function as its */ 73*37da2899SCharles.Forsyth /* first argument, and each field is thus accessed indirectly. */ 74*37da2899SCharles.Forsyth /* */ 75*37da2899SCharles.Forsyth /* This version is fully re-entrant. */ 76*37da2899SCharles.Forsyth /* */ 77*37da2899SCharles.Forsyth /* The idea is that an indirect implementation may be slower to execute */ 78*37da2899SCharles.Forsyth /* on low-end processors that are used in some systems (like 386s or */ 79*37da2899SCharles.Forsyth /* even 486s). */ 80*37da2899SCharles.Forsyth /* */ 81*37da2899SCharles.Forsyth /* As a consequence, the indirect implementation is now the default, as */ 82*37da2899SCharles.Forsyth /* its performance costs can be considered negligible in our context. */ 83*37da2899SCharles.Forsyth /* Note, however, that we kept the same source with macros because: */ 84*37da2899SCharles.Forsyth /* */ 85*37da2899SCharles.Forsyth /* - The code is kept very close in design to the Pascal code used for */ 86*37da2899SCharles.Forsyth /* development. */ 87*37da2899SCharles.Forsyth /* */ 88*37da2899SCharles.Forsyth /* - It's much more readable that way! */ 89*37da2899SCharles.Forsyth /* */ 90*37da2899SCharles.Forsyth /* - It's still open to experimentation and tuning. */ 91*37da2899SCharles.Forsyth /* */ 92*37da2899SCharles.Forsyth /*************************************************************************/ 93*37da2899SCharles.Forsyth 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth #ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ 96*37da2899SCharles.Forsyth 97*37da2899SCharles.Forsyth #define CUR (*exc) /* see ttobjs.h */ 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth #else /* static implementation */ 100*37da2899SCharles.Forsyth 101*37da2899SCharles.Forsyth #define CUR cur 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth static 104*37da2899SCharles.Forsyth TT_ExecContextRec cur; /* static exec. context variable */ 105*37da2899SCharles.Forsyth 106*37da2899SCharles.Forsyth /* apparently, we have a _lot_ of direct indexing when accessing */ 107*37da2899SCharles.Forsyth /* the static `cur', which makes the code bigger (due to all the */ 108*37da2899SCharles.Forsyth /* four bytes addresses). */ 109*37da2899SCharles.Forsyth 110*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth 113*37da2899SCharles.Forsyth /*************************************************************************/ 114*37da2899SCharles.Forsyth /* */ 115*37da2899SCharles.Forsyth /* The instruction argument stack. */ 116*37da2899SCharles.Forsyth /* */ 117*37da2899SCharles.Forsyth #define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ 118*37da2899SCharles.Forsyth 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth /*************************************************************************/ 121*37da2899SCharles.Forsyth /* */ 122*37da2899SCharles.Forsyth /* This macro is used whenever `exec' is unused in a function, to avoid */ 123*37da2899SCharles.Forsyth /* stupid warnings from pedantic compilers. */ 124*37da2899SCharles.Forsyth /* */ 125*37da2899SCharles.Forsyth #define FT_UNUSED_EXEC FT_UNUSED( CUR ) 126*37da2899SCharles.Forsyth 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth /*************************************************************************/ 129*37da2899SCharles.Forsyth /* */ 130*37da2899SCharles.Forsyth /* This macro is used whenever `args' is unused in a function, to avoid */ 131*37da2899SCharles.Forsyth /* stupid warnings from pedantic compilers. */ 132*37da2899SCharles.Forsyth /* */ 133*37da2899SCharles.Forsyth #define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) 134*37da2899SCharles.Forsyth 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth /*************************************************************************/ 137*37da2899SCharles.Forsyth /* */ 138*37da2899SCharles.Forsyth /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ 139*37da2899SCharles.Forsyth /* increase readabilty of the code. */ 140*37da2899SCharles.Forsyth /* */ 141*37da2899SCharles.Forsyth /*************************************************************************/ 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsyth 144*37da2899SCharles.Forsyth #define SKIP_Code() \ 145*37da2899SCharles.Forsyth SkipCode( EXEC_ARG ) 146*37da2899SCharles.Forsyth 147*37da2899SCharles.Forsyth #define GET_ShortIns() \ 148*37da2899SCharles.Forsyth GetShortIns( EXEC_ARG ) 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsyth #define NORMalize( x, y, v ) \ 151*37da2899SCharles.Forsyth Normalize( EXEC_ARG_ x, y, v ) 152*37da2899SCharles.Forsyth 153*37da2899SCharles.Forsyth #define SET_SuperRound( scale, flags ) \ 154*37da2899SCharles.Forsyth SetSuperRound( EXEC_ARG_ scale, flags ) 155*37da2899SCharles.Forsyth 156*37da2899SCharles.Forsyth #define ROUND_None( d, c ) \ 157*37da2899SCharles.Forsyth Round_None( EXEC_ARG_ d, c ) 158*37da2899SCharles.Forsyth 159*37da2899SCharles.Forsyth #define INS_Goto_CodeRange( range, ip ) \ 160*37da2899SCharles.Forsyth Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsyth #define CUR_Func_project( x, y ) \ 163*37da2899SCharles.Forsyth CUR.func_project( EXEC_ARG_ x, y ) 164*37da2899SCharles.Forsyth 165*37da2899SCharles.Forsyth #define CUR_Func_move( z, p, d ) \ 166*37da2899SCharles.Forsyth CUR.func_move( EXEC_ARG_ z, p, d ) 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth #define CUR_Func_dualproj( x, y ) \ 169*37da2899SCharles.Forsyth CUR.func_dualproj( EXEC_ARG_ x, y ) 170*37da2899SCharles.Forsyth 171*37da2899SCharles.Forsyth #define CUR_Func_freeProj( x, y ) \ 172*37da2899SCharles.Forsyth CUR.func_freeProj( EXEC_ARG_ x, y ) 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth #define CUR_Func_round( d, c ) \ 175*37da2899SCharles.Forsyth CUR.func_round( EXEC_ARG_ d, c ) 176*37da2899SCharles.Forsyth 177*37da2899SCharles.Forsyth #define CUR_Func_read_cvt( index ) \ 178*37da2899SCharles.Forsyth CUR.func_read_cvt( EXEC_ARG_ index ) 179*37da2899SCharles.Forsyth 180*37da2899SCharles.Forsyth #define CUR_Func_write_cvt( index, val ) \ 181*37da2899SCharles.Forsyth CUR.func_write_cvt( EXEC_ARG_ index, val ) 182*37da2899SCharles.Forsyth 183*37da2899SCharles.Forsyth #define CUR_Func_move_cvt( index, val ) \ 184*37da2899SCharles.Forsyth CUR.func_move_cvt( EXEC_ARG_ index, val ) 185*37da2899SCharles.Forsyth 186*37da2899SCharles.Forsyth #define CURRENT_Ratio() \ 187*37da2899SCharles.Forsyth Current_Ratio( EXEC_ARG ) 188*37da2899SCharles.Forsyth 189*37da2899SCharles.Forsyth #define CURRENT_Ppem() \ 190*37da2899SCharles.Forsyth Current_Ppem( EXEC_ARG ) 191*37da2899SCharles.Forsyth 192*37da2899SCharles.Forsyth #define CUR_Ppem() \ 193*37da2899SCharles.Forsyth Cur_PPEM( EXEC_ARG ) 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth #define INS_SxVTL( a, b, c, d ) \ 196*37da2899SCharles.Forsyth Ins_SxVTL( EXEC_ARG_ a, b, c, d ) 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth #define COMPUTE_Funcs() \ 199*37da2899SCharles.Forsyth Compute_Funcs( EXEC_ARG ) 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth #define COMPUTE_Round( a ) \ 202*37da2899SCharles.Forsyth Compute_Round( EXEC_ARG_ a ) 203*37da2899SCharles.Forsyth 204*37da2899SCharles.Forsyth #define COMPUTE_Point_Displacement( a, b, c, d ) \ 205*37da2899SCharles.Forsyth Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth #define MOVE_Zp2_Point( a, b, c, t ) \ 208*37da2899SCharles.Forsyth Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth /*************************************************************************/ 212*37da2899SCharles.Forsyth /* */ 213*37da2899SCharles.Forsyth /* Instruction dispatch function, as used by the interpreter. */ 214*37da2899SCharles.Forsyth /* */ 215*37da2899SCharles.Forsyth typedef void (*TInstruction_Function)( INS_ARG ); 216*37da2899SCharles.Forsyth 217*37da2899SCharles.Forsyth 218*37da2899SCharles.Forsyth /*************************************************************************/ 219*37da2899SCharles.Forsyth /* */ 220*37da2899SCharles.Forsyth /* A simple bounds-checking macro. */ 221*37da2899SCharles.Forsyth /* */ 222*37da2899SCharles.Forsyth #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsyth 225*37da2899SCharles.Forsyth #undef SUCCESS 226*37da2899SCharles.Forsyth #define SUCCESS 0 227*37da2899SCharles.Forsyth 228*37da2899SCharles.Forsyth #undef FAILURE 229*37da2899SCharles.Forsyth #define FAILURE 1 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth /*************************************************************************/ 233*37da2899SCharles.Forsyth /* */ 234*37da2899SCharles.Forsyth /* CODERANGE FUNCTIONS */ 235*37da2899SCharles.Forsyth /* */ 236*37da2899SCharles.Forsyth /*************************************************************************/ 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth 239*37da2899SCharles.Forsyth /*************************************************************************/ 240*37da2899SCharles.Forsyth /* */ 241*37da2899SCharles.Forsyth /* <Function> */ 242*37da2899SCharles.Forsyth /* TT_Goto_CodeRange */ 243*37da2899SCharles.Forsyth /* */ 244*37da2899SCharles.Forsyth /* <Description> */ 245*37da2899SCharles.Forsyth /* Switches to a new code range (updates the code related elements in */ 246*37da2899SCharles.Forsyth /* `exec', and `IP'). */ 247*37da2899SCharles.Forsyth /* */ 248*37da2899SCharles.Forsyth /* <Input> */ 249*37da2899SCharles.Forsyth /* range :: The new execution code range. */ 250*37da2899SCharles.Forsyth /* */ 251*37da2899SCharles.Forsyth /* IP :: The new IP in the new code range. */ 252*37da2899SCharles.Forsyth /* */ 253*37da2899SCharles.Forsyth /* <InOut> */ 254*37da2899SCharles.Forsyth /* exec :: The target execution context. */ 255*37da2899SCharles.Forsyth /* */ 256*37da2899SCharles.Forsyth /* <Return> */ 257*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 258*37da2899SCharles.Forsyth /* */ 259*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Goto_CodeRange(TT_ExecContext exec,FT_Int range,FT_Long IP)260*37da2899SCharles.Forsyth TT_Goto_CodeRange( TT_ExecContext exec, 261*37da2899SCharles.Forsyth FT_Int range, 262*37da2899SCharles.Forsyth FT_Long IP ) 263*37da2899SCharles.Forsyth { 264*37da2899SCharles.Forsyth TT_CodeRange* coderange; 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth 267*37da2899SCharles.Forsyth FT_ASSERT( range >= 1 && range <= 3 ); 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth coderange = &exec->codeRangeTable[range - 1]; 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth FT_ASSERT( coderange->base != NULL ); 272*37da2899SCharles.Forsyth 273*37da2899SCharles.Forsyth /* NOTE: Because the last instruction of a program may be a CALL */ 274*37da2899SCharles.Forsyth /* which will return to the first byte *after* the code */ 275*37da2899SCharles.Forsyth /* range, we test for IP <= Size instead of IP < Size. */ 276*37da2899SCharles.Forsyth /* */ 277*37da2899SCharles.Forsyth FT_ASSERT( (FT_ULong)IP <= coderange->size ); 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth exec->code = coderange->base; 280*37da2899SCharles.Forsyth exec->codeSize = coderange->size; 281*37da2899SCharles.Forsyth exec->IP = IP; 282*37da2899SCharles.Forsyth exec->curRange = range; 283*37da2899SCharles.Forsyth 284*37da2899SCharles.Forsyth return TT_Err_Ok; 285*37da2899SCharles.Forsyth } 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth /*************************************************************************/ 289*37da2899SCharles.Forsyth /* */ 290*37da2899SCharles.Forsyth /* <Function> */ 291*37da2899SCharles.Forsyth /* TT_Set_CodeRange */ 292*37da2899SCharles.Forsyth /* */ 293*37da2899SCharles.Forsyth /* <Description> */ 294*37da2899SCharles.Forsyth /* Sets a code range. */ 295*37da2899SCharles.Forsyth /* */ 296*37da2899SCharles.Forsyth /* <Input> */ 297*37da2899SCharles.Forsyth /* range :: The code range index. */ 298*37da2899SCharles.Forsyth /* */ 299*37da2899SCharles.Forsyth /* base :: The new code base. */ 300*37da2899SCharles.Forsyth /* */ 301*37da2899SCharles.Forsyth /* length :: The range size in bytes. */ 302*37da2899SCharles.Forsyth /* */ 303*37da2899SCharles.Forsyth /* <InOut> */ 304*37da2899SCharles.Forsyth /* exec :: The target execution context. */ 305*37da2899SCharles.Forsyth /* */ 306*37da2899SCharles.Forsyth /* <Return> */ 307*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 308*37da2899SCharles.Forsyth /* */ 309*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Set_CodeRange(TT_ExecContext exec,FT_Int range,void * base,FT_Long length)310*37da2899SCharles.Forsyth TT_Set_CodeRange( TT_ExecContext exec, 311*37da2899SCharles.Forsyth FT_Int range, 312*37da2899SCharles.Forsyth void* base, 313*37da2899SCharles.Forsyth FT_Long length ) 314*37da2899SCharles.Forsyth { 315*37da2899SCharles.Forsyth FT_ASSERT( range >= 1 && range <= 3 ); 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth exec->codeRangeTable[range - 1].base = (FT_Byte*)base; 318*37da2899SCharles.Forsyth exec->codeRangeTable[range - 1].size = length; 319*37da2899SCharles.Forsyth 320*37da2899SCharles.Forsyth return TT_Err_Ok; 321*37da2899SCharles.Forsyth } 322*37da2899SCharles.Forsyth 323*37da2899SCharles.Forsyth 324*37da2899SCharles.Forsyth /*************************************************************************/ 325*37da2899SCharles.Forsyth /* */ 326*37da2899SCharles.Forsyth /* <Function> */ 327*37da2899SCharles.Forsyth /* TT_Clear_CodeRange */ 328*37da2899SCharles.Forsyth /* */ 329*37da2899SCharles.Forsyth /* <Description> */ 330*37da2899SCharles.Forsyth /* Clears a code range. */ 331*37da2899SCharles.Forsyth /* */ 332*37da2899SCharles.Forsyth /* <Input> */ 333*37da2899SCharles.Forsyth /* range :: The code range index. */ 334*37da2899SCharles.Forsyth /* */ 335*37da2899SCharles.Forsyth /* <InOut> */ 336*37da2899SCharles.Forsyth /* exec :: The target execution context. */ 337*37da2899SCharles.Forsyth /* */ 338*37da2899SCharles.Forsyth /* <Return> */ 339*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 340*37da2899SCharles.Forsyth /* */ 341*37da2899SCharles.Forsyth /* <Note> */ 342*37da2899SCharles.Forsyth /* Does not set the Error variable. */ 343*37da2899SCharles.Forsyth /* */ 344*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Clear_CodeRange(TT_ExecContext exec,FT_Int range)345*37da2899SCharles.Forsyth TT_Clear_CodeRange( TT_ExecContext exec, 346*37da2899SCharles.Forsyth FT_Int range ) 347*37da2899SCharles.Forsyth { 348*37da2899SCharles.Forsyth FT_ASSERT( range >= 1 && range <= 3 ); 349*37da2899SCharles.Forsyth 350*37da2899SCharles.Forsyth exec->codeRangeTable[range - 1].base = NULL; 351*37da2899SCharles.Forsyth exec->codeRangeTable[range - 1].size = 0; 352*37da2899SCharles.Forsyth 353*37da2899SCharles.Forsyth return TT_Err_Ok; 354*37da2899SCharles.Forsyth } 355*37da2899SCharles.Forsyth 356*37da2899SCharles.Forsyth 357*37da2899SCharles.Forsyth /*************************************************************************/ 358*37da2899SCharles.Forsyth /* */ 359*37da2899SCharles.Forsyth /* EXECUTION CONTEXT ROUTINES */ 360*37da2899SCharles.Forsyth /* */ 361*37da2899SCharles.Forsyth /*************************************************************************/ 362*37da2899SCharles.Forsyth 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth /*************************************************************************/ 365*37da2899SCharles.Forsyth /* */ 366*37da2899SCharles.Forsyth /* <Function> */ 367*37da2899SCharles.Forsyth /* TT_Destroy_Context */ 368*37da2899SCharles.Forsyth /* */ 369*37da2899SCharles.Forsyth /* <Description> */ 370*37da2899SCharles.Forsyth /* Destroys a given context. */ 371*37da2899SCharles.Forsyth /* */ 372*37da2899SCharles.Forsyth /* <Input> */ 373*37da2899SCharles.Forsyth /* exec :: A handle to the target execution context. */ 374*37da2899SCharles.Forsyth /* */ 375*37da2899SCharles.Forsyth /* memory :: A handle to the parent memory object. */ 376*37da2899SCharles.Forsyth /* */ 377*37da2899SCharles.Forsyth /* <Return> */ 378*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 379*37da2899SCharles.Forsyth /* */ 380*37da2899SCharles.Forsyth /* <Note> */ 381*37da2899SCharles.Forsyth /* Only the glyph loader and debugger should call this function. */ 382*37da2899SCharles.Forsyth /* */ 383*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Destroy_Context(TT_ExecContext exec,FT_Memory memory)384*37da2899SCharles.Forsyth TT_Destroy_Context( TT_ExecContext exec, 385*37da2899SCharles.Forsyth FT_Memory memory ) 386*37da2899SCharles.Forsyth { 387*37da2899SCharles.Forsyth /* free composite load stack */ 388*37da2899SCharles.Forsyth FT_FREE( exec->loadStack ); 389*37da2899SCharles.Forsyth exec->loadSize = 0; 390*37da2899SCharles.Forsyth 391*37da2899SCharles.Forsyth /* points zone */ 392*37da2899SCharles.Forsyth exec->maxPoints = 0; 393*37da2899SCharles.Forsyth exec->maxContours = 0; 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth /* free stack */ 396*37da2899SCharles.Forsyth FT_FREE( exec->stack ); 397*37da2899SCharles.Forsyth exec->stackSize = 0; 398*37da2899SCharles.Forsyth 399*37da2899SCharles.Forsyth /* free call stack */ 400*37da2899SCharles.Forsyth FT_FREE( exec->callStack ); 401*37da2899SCharles.Forsyth exec->callSize = 0; 402*37da2899SCharles.Forsyth exec->callTop = 0; 403*37da2899SCharles.Forsyth 404*37da2899SCharles.Forsyth /* free glyph code range */ 405*37da2899SCharles.Forsyth FT_FREE( exec->glyphIns ); 406*37da2899SCharles.Forsyth exec->glyphSize = 0; 407*37da2899SCharles.Forsyth 408*37da2899SCharles.Forsyth exec->size = NULL; 409*37da2899SCharles.Forsyth exec->face = NULL; 410*37da2899SCharles.Forsyth 411*37da2899SCharles.Forsyth FT_FREE( exec ); 412*37da2899SCharles.Forsyth return TT_Err_Ok; 413*37da2899SCharles.Forsyth } 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsyth /*************************************************************************/ 417*37da2899SCharles.Forsyth /* */ 418*37da2899SCharles.Forsyth /* <Function> */ 419*37da2899SCharles.Forsyth /* Init_Context */ 420*37da2899SCharles.Forsyth /* */ 421*37da2899SCharles.Forsyth /* <Description> */ 422*37da2899SCharles.Forsyth /* Initializes a context object. */ 423*37da2899SCharles.Forsyth /* */ 424*37da2899SCharles.Forsyth /* <Input> */ 425*37da2899SCharles.Forsyth /* memory :: A handle to the parent memory object. */ 426*37da2899SCharles.Forsyth /* */ 427*37da2899SCharles.Forsyth /* face :: A handle to the source TrueType face object. */ 428*37da2899SCharles.Forsyth /* */ 429*37da2899SCharles.Forsyth /* <InOut> */ 430*37da2899SCharles.Forsyth /* exec :: A handle to the target execution context. */ 431*37da2899SCharles.Forsyth /* */ 432*37da2899SCharles.Forsyth /* <Return> */ 433*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 434*37da2899SCharles.Forsyth /* */ 435*37da2899SCharles.Forsyth static FT_Error Init_Context(TT_ExecContext exec,TT_Face face,FT_Memory memory)436*37da2899SCharles.Forsyth Init_Context( TT_ExecContext exec, 437*37da2899SCharles.Forsyth TT_Face face, 438*37da2899SCharles.Forsyth FT_Memory memory ) 439*37da2899SCharles.Forsyth { 440*37da2899SCharles.Forsyth FT_Error error; 441*37da2899SCharles.Forsyth 442*37da2899SCharles.Forsyth 443*37da2899SCharles.Forsyth FT_TRACE1(( "Init_Context: new object at 0x%08p, parent = 0x%08p\n", 444*37da2899SCharles.Forsyth exec, face )); 445*37da2899SCharles.Forsyth 446*37da2899SCharles.Forsyth exec->memory = memory; 447*37da2899SCharles.Forsyth exec->callSize = 32; 448*37da2899SCharles.Forsyth 449*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) 450*37da2899SCharles.Forsyth goto Fail_Memory; 451*37da2899SCharles.Forsyth 452*37da2899SCharles.Forsyth /* all values in the context are set to 0 already, but this is */ 453*37da2899SCharles.Forsyth /* here as a remainder */ 454*37da2899SCharles.Forsyth exec->maxPoints = 0; 455*37da2899SCharles.Forsyth exec->maxContours = 0; 456*37da2899SCharles.Forsyth 457*37da2899SCharles.Forsyth exec->stackSize = 0; 458*37da2899SCharles.Forsyth exec->loadSize = 0; 459*37da2899SCharles.Forsyth exec->glyphSize = 0; 460*37da2899SCharles.Forsyth 461*37da2899SCharles.Forsyth exec->stack = NULL; 462*37da2899SCharles.Forsyth exec->loadStack = NULL; 463*37da2899SCharles.Forsyth exec->glyphIns = NULL; 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth exec->face = face; 466*37da2899SCharles.Forsyth exec->size = NULL; 467*37da2899SCharles.Forsyth 468*37da2899SCharles.Forsyth return TT_Err_Ok; 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth Fail_Memory: 471*37da2899SCharles.Forsyth FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n", 472*37da2899SCharles.Forsyth (FT_Long)exec )); 473*37da2899SCharles.Forsyth TT_Destroy_Context( exec, memory ); 474*37da2899SCharles.Forsyth 475*37da2899SCharles.Forsyth return error; 476*37da2899SCharles.Forsyth } 477*37da2899SCharles.Forsyth 478*37da2899SCharles.Forsyth 479*37da2899SCharles.Forsyth /*************************************************************************/ 480*37da2899SCharles.Forsyth /* */ 481*37da2899SCharles.Forsyth /* <Function> */ 482*37da2899SCharles.Forsyth /* Update_Max */ 483*37da2899SCharles.Forsyth /* */ 484*37da2899SCharles.Forsyth /* <Description> */ 485*37da2899SCharles.Forsyth /* Checks the size of a buffer and reallocates it if necessary. */ 486*37da2899SCharles.Forsyth /* */ 487*37da2899SCharles.Forsyth /* <Input> */ 488*37da2899SCharles.Forsyth /* memory :: A handle to the parent memory object. */ 489*37da2899SCharles.Forsyth /* */ 490*37da2899SCharles.Forsyth /* multiplier :: The size in bytes of each element in the buffer. */ 491*37da2899SCharles.Forsyth /* */ 492*37da2899SCharles.Forsyth /* new_max :: The new capacity (size) of the buffer. */ 493*37da2899SCharles.Forsyth /* */ 494*37da2899SCharles.Forsyth /* <InOut> */ 495*37da2899SCharles.Forsyth /* size :: The address of the buffer's current size expressed */ 496*37da2899SCharles.Forsyth /* in elements. */ 497*37da2899SCharles.Forsyth /* */ 498*37da2899SCharles.Forsyth /* buff :: The address of the buffer base pointer. */ 499*37da2899SCharles.Forsyth /* */ 500*37da2899SCharles.Forsyth /* <Return> */ 501*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 502*37da2899SCharles.Forsyth /* */ 503*37da2899SCharles.Forsyth static FT_Error Update_Max(FT_Memory memory,FT_ULong * size,FT_Long multiplier,void ** buff,FT_ULong new_max)504*37da2899SCharles.Forsyth Update_Max( FT_Memory memory, 505*37da2899SCharles.Forsyth FT_ULong* size, 506*37da2899SCharles.Forsyth FT_Long multiplier, 507*37da2899SCharles.Forsyth void** buff, 508*37da2899SCharles.Forsyth FT_ULong new_max ) 509*37da2899SCharles.Forsyth { 510*37da2899SCharles.Forsyth FT_Error error; 511*37da2899SCharles.Forsyth 512*37da2899SCharles.Forsyth 513*37da2899SCharles.Forsyth if ( *size < new_max ) 514*37da2899SCharles.Forsyth { 515*37da2899SCharles.Forsyth FT_FREE( *buff ); 516*37da2899SCharles.Forsyth if ( FT_ALLOC( *buff, new_max * multiplier ) ) 517*37da2899SCharles.Forsyth return error; 518*37da2899SCharles.Forsyth *size = new_max; 519*37da2899SCharles.Forsyth } 520*37da2899SCharles.Forsyth 521*37da2899SCharles.Forsyth return TT_Err_Ok; 522*37da2899SCharles.Forsyth } 523*37da2899SCharles.Forsyth 524*37da2899SCharles.Forsyth 525*37da2899SCharles.Forsyth /*************************************************************************/ 526*37da2899SCharles.Forsyth /* */ 527*37da2899SCharles.Forsyth /* <Function> */ 528*37da2899SCharles.Forsyth /* TT_Load_Context */ 529*37da2899SCharles.Forsyth /* */ 530*37da2899SCharles.Forsyth /* <Description> */ 531*37da2899SCharles.Forsyth /* Prepare an execution context for glyph hinting. */ 532*37da2899SCharles.Forsyth /* */ 533*37da2899SCharles.Forsyth /* <Input> */ 534*37da2899SCharles.Forsyth /* face :: A handle to the source face object. */ 535*37da2899SCharles.Forsyth /* */ 536*37da2899SCharles.Forsyth /* size :: A handle to the source size object. */ 537*37da2899SCharles.Forsyth /* */ 538*37da2899SCharles.Forsyth /* <InOut> */ 539*37da2899SCharles.Forsyth /* exec :: A handle to the target execution context. */ 540*37da2899SCharles.Forsyth /* */ 541*37da2899SCharles.Forsyth /* <Return> */ 542*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 543*37da2899SCharles.Forsyth /* */ 544*37da2899SCharles.Forsyth /* <Note> */ 545*37da2899SCharles.Forsyth /* Only the glyph loader and debugger should call this function. */ 546*37da2899SCharles.Forsyth /* */ 547*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Load_Context(TT_ExecContext exec,TT_Face face,TT_Size size)548*37da2899SCharles.Forsyth TT_Load_Context( TT_ExecContext exec, 549*37da2899SCharles.Forsyth TT_Face face, 550*37da2899SCharles.Forsyth TT_Size size ) 551*37da2899SCharles.Forsyth { 552*37da2899SCharles.Forsyth FT_Int i; 553*37da2899SCharles.Forsyth FT_ULong tmp; 554*37da2899SCharles.Forsyth TT_MaxProfile* maxp; 555*37da2899SCharles.Forsyth FT_Error error; 556*37da2899SCharles.Forsyth 557*37da2899SCharles.Forsyth 558*37da2899SCharles.Forsyth exec->face = face; 559*37da2899SCharles.Forsyth maxp = &face->max_profile; 560*37da2899SCharles.Forsyth exec->size = size; 561*37da2899SCharles.Forsyth 562*37da2899SCharles.Forsyth if ( size ) 563*37da2899SCharles.Forsyth { 564*37da2899SCharles.Forsyth exec->numFDefs = size->num_function_defs; 565*37da2899SCharles.Forsyth exec->maxFDefs = size->max_function_defs; 566*37da2899SCharles.Forsyth exec->numIDefs = size->num_instruction_defs; 567*37da2899SCharles.Forsyth exec->maxIDefs = size->max_instruction_defs; 568*37da2899SCharles.Forsyth exec->FDefs = size->function_defs; 569*37da2899SCharles.Forsyth exec->IDefs = size->instruction_defs; 570*37da2899SCharles.Forsyth exec->tt_metrics = size->ttmetrics; 571*37da2899SCharles.Forsyth exec->metrics = size->root.metrics; 572*37da2899SCharles.Forsyth 573*37da2899SCharles.Forsyth exec->maxFunc = size->max_func; 574*37da2899SCharles.Forsyth exec->maxIns = size->max_ins; 575*37da2899SCharles.Forsyth 576*37da2899SCharles.Forsyth for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) 577*37da2899SCharles.Forsyth exec->codeRangeTable[i] = size->codeRangeTable[i]; 578*37da2899SCharles.Forsyth 579*37da2899SCharles.Forsyth /* set graphics state */ 580*37da2899SCharles.Forsyth exec->GS = size->GS; 581*37da2899SCharles.Forsyth 582*37da2899SCharles.Forsyth exec->cvtSize = size->cvt_size; 583*37da2899SCharles.Forsyth exec->cvt = size->cvt; 584*37da2899SCharles.Forsyth 585*37da2899SCharles.Forsyth exec->storeSize = size->storage_size; 586*37da2899SCharles.Forsyth exec->storage = size->storage; 587*37da2899SCharles.Forsyth 588*37da2899SCharles.Forsyth exec->twilight = size->twilight; 589*37da2899SCharles.Forsyth } 590*37da2899SCharles.Forsyth 591*37da2899SCharles.Forsyth error = Update_Max( exec->memory, 592*37da2899SCharles.Forsyth &exec->loadSize, 593*37da2899SCharles.Forsyth sizeof ( TT_SubGlyphRec ), 594*37da2899SCharles.Forsyth (void**)&exec->loadStack, 595*37da2899SCharles.Forsyth exec->face->max_components + 1 ); 596*37da2899SCharles.Forsyth if ( error ) 597*37da2899SCharles.Forsyth return error; 598*37da2899SCharles.Forsyth 599*37da2899SCharles.Forsyth /* XXX: We reserve a little more elements on the stack to deal safely */ 600*37da2899SCharles.Forsyth /* with broken fonts like arialbs, courbs, timesbs, etc. */ 601*37da2899SCharles.Forsyth tmp = exec->stackSize; 602*37da2899SCharles.Forsyth error = Update_Max( exec->memory, 603*37da2899SCharles.Forsyth &tmp, 604*37da2899SCharles.Forsyth sizeof ( FT_F26Dot6 ), 605*37da2899SCharles.Forsyth (void**)&exec->stack, 606*37da2899SCharles.Forsyth maxp->maxStackElements + 32 ); 607*37da2899SCharles.Forsyth exec->stackSize = (FT_UInt)tmp; 608*37da2899SCharles.Forsyth if ( error ) 609*37da2899SCharles.Forsyth return error; 610*37da2899SCharles.Forsyth 611*37da2899SCharles.Forsyth tmp = exec->glyphSize; 612*37da2899SCharles.Forsyth error = Update_Max( exec->memory, 613*37da2899SCharles.Forsyth &tmp, 614*37da2899SCharles.Forsyth sizeof ( FT_Byte ), 615*37da2899SCharles.Forsyth (void**)&exec->glyphIns, 616*37da2899SCharles.Forsyth maxp->maxSizeOfInstructions ); 617*37da2899SCharles.Forsyth exec->glyphSize = (FT_UShort)tmp; 618*37da2899SCharles.Forsyth if ( error ) 619*37da2899SCharles.Forsyth return error; 620*37da2899SCharles.Forsyth 621*37da2899SCharles.Forsyth exec->pts.n_points = 0; 622*37da2899SCharles.Forsyth exec->pts.n_contours = 0; 623*37da2899SCharles.Forsyth 624*37da2899SCharles.Forsyth exec->instruction_trap = FALSE; 625*37da2899SCharles.Forsyth 626*37da2899SCharles.Forsyth return TT_Err_Ok; 627*37da2899SCharles.Forsyth } 628*37da2899SCharles.Forsyth 629*37da2899SCharles.Forsyth 630*37da2899SCharles.Forsyth /*************************************************************************/ 631*37da2899SCharles.Forsyth /* */ 632*37da2899SCharles.Forsyth /* <Function> */ 633*37da2899SCharles.Forsyth /* TT_Save_Context */ 634*37da2899SCharles.Forsyth /* */ 635*37da2899SCharles.Forsyth /* <Description> */ 636*37da2899SCharles.Forsyth /* Saves the code ranges in a `size' object. */ 637*37da2899SCharles.Forsyth /* */ 638*37da2899SCharles.Forsyth /* <Input> */ 639*37da2899SCharles.Forsyth /* exec :: A handle to the source execution context. */ 640*37da2899SCharles.Forsyth /* */ 641*37da2899SCharles.Forsyth /* <InOut> */ 642*37da2899SCharles.Forsyth /* size :: A handle to the target size object. */ 643*37da2899SCharles.Forsyth /* */ 644*37da2899SCharles.Forsyth /* <Return> */ 645*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 646*37da2899SCharles.Forsyth /* */ 647*37da2899SCharles.Forsyth /* <Note> */ 648*37da2899SCharles.Forsyth /* Only the glyph loader and debugger should call this function. */ 649*37da2899SCharles.Forsyth /* */ 650*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Save_Context(TT_ExecContext exec,TT_Size size)651*37da2899SCharles.Forsyth TT_Save_Context( TT_ExecContext exec, 652*37da2899SCharles.Forsyth TT_Size size ) 653*37da2899SCharles.Forsyth { 654*37da2899SCharles.Forsyth FT_Int i; 655*37da2899SCharles.Forsyth 656*37da2899SCharles.Forsyth 657*37da2899SCharles.Forsyth /* XXXX: Will probably disappear soon with all the code range */ 658*37da2899SCharles.Forsyth /* management, which is now rather obsolete. */ 659*37da2899SCharles.Forsyth /* */ 660*37da2899SCharles.Forsyth size->num_function_defs = exec->numFDefs; 661*37da2899SCharles.Forsyth size->num_instruction_defs = exec->numIDefs; 662*37da2899SCharles.Forsyth 663*37da2899SCharles.Forsyth size->max_func = exec->maxFunc; 664*37da2899SCharles.Forsyth size->max_ins = exec->maxIns; 665*37da2899SCharles.Forsyth 666*37da2899SCharles.Forsyth for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) 667*37da2899SCharles.Forsyth size->codeRangeTable[i] = exec->codeRangeTable[i]; 668*37da2899SCharles.Forsyth 669*37da2899SCharles.Forsyth return TT_Err_Ok; 670*37da2899SCharles.Forsyth } 671*37da2899SCharles.Forsyth 672*37da2899SCharles.Forsyth 673*37da2899SCharles.Forsyth /*************************************************************************/ 674*37da2899SCharles.Forsyth /* */ 675*37da2899SCharles.Forsyth /* <Function> */ 676*37da2899SCharles.Forsyth /* TT_Run_Context */ 677*37da2899SCharles.Forsyth /* */ 678*37da2899SCharles.Forsyth /* <Description> */ 679*37da2899SCharles.Forsyth /* Executes one or more instructions in the execution context. */ 680*37da2899SCharles.Forsyth /* */ 681*37da2899SCharles.Forsyth /* <Input> */ 682*37da2899SCharles.Forsyth /* debug :: A Boolean flag. If set, the function sets some internal */ 683*37da2899SCharles.Forsyth /* variables and returns immediately, otherwise TT_RunIns() */ 684*37da2899SCharles.Forsyth /* is called. */ 685*37da2899SCharles.Forsyth /* */ 686*37da2899SCharles.Forsyth /* This is commented out currently. */ 687*37da2899SCharles.Forsyth /* */ 688*37da2899SCharles.Forsyth /* <Input> */ 689*37da2899SCharles.Forsyth /* exec :: A handle to the target execution context. */ 690*37da2899SCharles.Forsyth /* */ 691*37da2899SCharles.Forsyth /* <Return> */ 692*37da2899SCharles.Forsyth /* TrueTyoe error code. 0 means success. */ 693*37da2899SCharles.Forsyth /* */ 694*37da2899SCharles.Forsyth /* <Note> */ 695*37da2899SCharles.Forsyth /* Only the glyph loader and debugger should call this function. */ 696*37da2899SCharles.Forsyth /* */ 697*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Run_Context(TT_ExecContext exec,FT_Bool debug)698*37da2899SCharles.Forsyth TT_Run_Context( TT_ExecContext exec, 699*37da2899SCharles.Forsyth FT_Bool debug ) 700*37da2899SCharles.Forsyth { 701*37da2899SCharles.Forsyth FT_Error error; 702*37da2899SCharles.Forsyth 703*37da2899SCharles.Forsyth 704*37da2899SCharles.Forsyth if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) 705*37da2899SCharles.Forsyth != TT_Err_Ok ) 706*37da2899SCharles.Forsyth return error; 707*37da2899SCharles.Forsyth 708*37da2899SCharles.Forsyth exec->zp0 = exec->pts; 709*37da2899SCharles.Forsyth exec->zp1 = exec->pts; 710*37da2899SCharles.Forsyth exec->zp2 = exec->pts; 711*37da2899SCharles.Forsyth 712*37da2899SCharles.Forsyth exec->GS.gep0 = 1; 713*37da2899SCharles.Forsyth exec->GS.gep1 = 1; 714*37da2899SCharles.Forsyth exec->GS.gep2 = 1; 715*37da2899SCharles.Forsyth 716*37da2899SCharles.Forsyth exec->GS.projVector.x = 0x4000; 717*37da2899SCharles.Forsyth exec->GS.projVector.y = 0x0000; 718*37da2899SCharles.Forsyth 719*37da2899SCharles.Forsyth exec->GS.freeVector = exec->GS.projVector; 720*37da2899SCharles.Forsyth exec->GS.dualVector = exec->GS.projVector; 721*37da2899SCharles.Forsyth 722*37da2899SCharles.Forsyth exec->GS.round_state = 1; 723*37da2899SCharles.Forsyth exec->GS.loop = 1; 724*37da2899SCharles.Forsyth 725*37da2899SCharles.Forsyth /* some glyphs leave something on the stack. so we clean it */ 726*37da2899SCharles.Forsyth /* before a new execution. */ 727*37da2899SCharles.Forsyth exec->top = 0; 728*37da2899SCharles.Forsyth exec->callTop = 0; 729*37da2899SCharles.Forsyth 730*37da2899SCharles.Forsyth #if 1 731*37da2899SCharles.Forsyth FT_UNUSED( debug ); 732*37da2899SCharles.Forsyth 733*37da2899SCharles.Forsyth return exec->face->interpreter( exec ); 734*37da2899SCharles.Forsyth #else 735*37da2899SCharles.Forsyth if ( !debug ) 736*37da2899SCharles.Forsyth return TT_RunIns( exec ); 737*37da2899SCharles.Forsyth else 738*37da2899SCharles.Forsyth return TT_Err_Ok; 739*37da2899SCharles.Forsyth #endif 740*37da2899SCharles.Forsyth } 741*37da2899SCharles.Forsyth 742*37da2899SCharles.Forsyth 743*37da2899SCharles.Forsyth const TT_GraphicsState tt_default_graphics_state = 744*37da2899SCharles.Forsyth { 745*37da2899SCharles.Forsyth 0, 0, 0, 746*37da2899SCharles.Forsyth { 0x4000, 0 }, 747*37da2899SCharles.Forsyth { 0x4000, 0 }, 748*37da2899SCharles.Forsyth { 0x4000, 0 }, 749*37da2899SCharles.Forsyth 1, 64, 1, 750*37da2899SCharles.Forsyth TRUE, 68, 0, 0, 9, 3, 751*37da2899SCharles.Forsyth 0, FALSE, 2, 1, 1, 1 752*37da2899SCharles.Forsyth }; 753*37da2899SCharles.Forsyth 754*37da2899SCharles.Forsyth 755*37da2899SCharles.Forsyth /* documentation is in ttinterp.h */ 756*37da2899SCharles.Forsyth 757*37da2899SCharles.Forsyth FT_EXPORT_DEF( TT_ExecContext ) TT_New_Context(TT_Face face)758*37da2899SCharles.Forsyth TT_New_Context( TT_Face face ) 759*37da2899SCharles.Forsyth { 760*37da2899SCharles.Forsyth TT_Driver driver; 761*37da2899SCharles.Forsyth TT_ExecContext exec; 762*37da2899SCharles.Forsyth FT_Memory memory; 763*37da2899SCharles.Forsyth 764*37da2899SCharles.Forsyth 765*37da2899SCharles.Forsyth if ( !face ) 766*37da2899SCharles.Forsyth return 0; 767*37da2899SCharles.Forsyth 768*37da2899SCharles.Forsyth driver = (TT_Driver)face->root.driver; 769*37da2899SCharles.Forsyth 770*37da2899SCharles.Forsyth memory = driver->root.root.memory; 771*37da2899SCharles.Forsyth exec = driver->context; 772*37da2899SCharles.Forsyth 773*37da2899SCharles.Forsyth if ( !driver->context ) 774*37da2899SCharles.Forsyth { 775*37da2899SCharles.Forsyth FT_Error error; 776*37da2899SCharles.Forsyth 777*37da2899SCharles.Forsyth 778*37da2899SCharles.Forsyth /* allocate object */ 779*37da2899SCharles.Forsyth if ( FT_NEW( exec ) ) 780*37da2899SCharles.Forsyth goto Exit; 781*37da2899SCharles.Forsyth 782*37da2899SCharles.Forsyth /* initialize it */ 783*37da2899SCharles.Forsyth error = Init_Context( exec, face, memory ); 784*37da2899SCharles.Forsyth if ( error ) 785*37da2899SCharles.Forsyth goto Fail; 786*37da2899SCharles.Forsyth 787*37da2899SCharles.Forsyth /* store it into the driver */ 788*37da2899SCharles.Forsyth driver->context = exec; 789*37da2899SCharles.Forsyth } 790*37da2899SCharles.Forsyth 791*37da2899SCharles.Forsyth Exit: 792*37da2899SCharles.Forsyth return driver->context; 793*37da2899SCharles.Forsyth 794*37da2899SCharles.Forsyth Fail: 795*37da2899SCharles.Forsyth FT_FREE( exec ); 796*37da2899SCharles.Forsyth 797*37da2899SCharles.Forsyth return 0; 798*37da2899SCharles.Forsyth } 799*37da2899SCharles.Forsyth 800*37da2899SCharles.Forsyth 801*37da2899SCharles.Forsyth /*************************************************************************/ 802*37da2899SCharles.Forsyth /* */ 803*37da2899SCharles.Forsyth /* <Function> */ 804*37da2899SCharles.Forsyth /* TT_Done_Context */ 805*37da2899SCharles.Forsyth /* */ 806*37da2899SCharles.Forsyth /* <Description> */ 807*37da2899SCharles.Forsyth /* Discards an execution context. */ 808*37da2899SCharles.Forsyth /* */ 809*37da2899SCharles.Forsyth /* <Input> */ 810*37da2899SCharles.Forsyth /* exec :: A handle to the target execution context. */ 811*37da2899SCharles.Forsyth /* */ 812*37da2899SCharles.Forsyth /* <Return> */ 813*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 814*37da2899SCharles.Forsyth /* */ 815*37da2899SCharles.Forsyth /* <Note> */ 816*37da2899SCharles.Forsyth /* Only the glyph loader and debugger should call this function. */ 817*37da2899SCharles.Forsyth /* */ 818*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) TT_Done_Context(TT_ExecContext exec)819*37da2899SCharles.Forsyth TT_Done_Context( TT_ExecContext exec ) 820*37da2899SCharles.Forsyth { 821*37da2899SCharles.Forsyth /* Nothing at all for now */ 822*37da2899SCharles.Forsyth FT_UNUSED( exec ); 823*37da2899SCharles.Forsyth 824*37da2899SCharles.Forsyth return TT_Err_Ok; 825*37da2899SCharles.Forsyth } 826*37da2899SCharles.Forsyth 827*37da2899SCharles.Forsyth 828*37da2899SCharles.Forsyth 829*37da2899SCharles.Forsyth /*************************************************************************/ 830*37da2899SCharles.Forsyth /* */ 831*37da2899SCharles.Forsyth /* Before an opcode is executed, the interpreter verifies that there are */ 832*37da2899SCharles.Forsyth /* enough arguments on the stack, with the help of the Pop_Push_Count */ 833*37da2899SCharles.Forsyth /* table. */ 834*37da2899SCharles.Forsyth /* */ 835*37da2899SCharles.Forsyth /* For each opcode, the first column gives the number of arguments that */ 836*37da2899SCharles.Forsyth /* are popped from the stack; the second one gives the number of those */ 837*37da2899SCharles.Forsyth /* that are pushed in result. */ 838*37da2899SCharles.Forsyth /* */ 839*37da2899SCharles.Forsyth /* Note that for opcodes with a varying number of parameters, either 0 */ 840*37da2899SCharles.Forsyth /* or 1 arg is verified before execution, depending on the nature of the */ 841*37da2899SCharles.Forsyth /* instruction: */ 842*37da2899SCharles.Forsyth /* */ 843*37da2899SCharles.Forsyth /* - if the number of arguments is given by the bytecode stream or the */ 844*37da2899SCharles.Forsyth /* loop variable, 0 is chosen. */ 845*37da2899SCharles.Forsyth /* */ 846*37da2899SCharles.Forsyth /* - if the first argument is a count n that is followed by arguments */ 847*37da2899SCharles.Forsyth /* a1 .. an, then 1 is chosen. */ 848*37da2899SCharles.Forsyth /* */ 849*37da2899SCharles.Forsyth /*************************************************************************/ 850*37da2899SCharles.Forsyth 851*37da2899SCharles.Forsyth 852*37da2899SCharles.Forsyth #undef PACK 853*37da2899SCharles.Forsyth #define PACK( x, y ) ( ( x << 4 ) | y ) 854*37da2899SCharles.Forsyth 855*37da2899SCharles.Forsyth 856*37da2899SCharles.Forsyth static 857*37da2899SCharles.Forsyth const FT_Byte Pop_Push_Count[256] = 858*37da2899SCharles.Forsyth { 859*37da2899SCharles.Forsyth /* opcodes are gathered in groups of 16 */ 860*37da2899SCharles.Forsyth /* please keep the spaces as they are */ 861*37da2899SCharles.Forsyth 862*37da2899SCharles.Forsyth /* SVTCA y */ PACK( 0, 0 ), 863*37da2899SCharles.Forsyth /* SVTCA x */ PACK( 0, 0 ), 864*37da2899SCharles.Forsyth /* SPvTCA y */ PACK( 0, 0 ), 865*37da2899SCharles.Forsyth /* SPvTCA x */ PACK( 0, 0 ), 866*37da2899SCharles.Forsyth /* SFvTCA y */ PACK( 0, 0 ), 867*37da2899SCharles.Forsyth /* SFvTCA x */ PACK( 0, 0 ), 868*37da2899SCharles.Forsyth /* SPvTL // */ PACK( 2, 0 ), 869*37da2899SCharles.Forsyth /* SPvTL + */ PACK( 2, 0 ), 870*37da2899SCharles.Forsyth /* SFvTL // */ PACK( 2, 0 ), 871*37da2899SCharles.Forsyth /* SFvTL + */ PACK( 2, 0 ), 872*37da2899SCharles.Forsyth /* SPvFS */ PACK( 2, 0 ), 873*37da2899SCharles.Forsyth /* SFvFS */ PACK( 2, 0 ), 874*37da2899SCharles.Forsyth /* GPV */ PACK( 0, 2 ), 875*37da2899SCharles.Forsyth /* GFV */ PACK( 0, 2 ), 876*37da2899SCharles.Forsyth /* SFvTPv */ PACK( 0, 0 ), 877*37da2899SCharles.Forsyth /* ISECT */ PACK( 5, 0 ), 878*37da2899SCharles.Forsyth 879*37da2899SCharles.Forsyth /* SRP0 */ PACK( 1, 0 ), 880*37da2899SCharles.Forsyth /* SRP1 */ PACK( 1, 0 ), 881*37da2899SCharles.Forsyth /* SRP2 */ PACK( 1, 0 ), 882*37da2899SCharles.Forsyth /* SZP0 */ PACK( 1, 0 ), 883*37da2899SCharles.Forsyth /* SZP1 */ PACK( 1, 0 ), 884*37da2899SCharles.Forsyth /* SZP2 */ PACK( 1, 0 ), 885*37da2899SCharles.Forsyth /* SZPS */ PACK( 1, 0 ), 886*37da2899SCharles.Forsyth /* SLOOP */ PACK( 1, 0 ), 887*37da2899SCharles.Forsyth /* RTG */ PACK( 0, 0 ), 888*37da2899SCharles.Forsyth /* RTHG */ PACK( 0, 0 ), 889*37da2899SCharles.Forsyth /* SMD */ PACK( 1, 0 ), 890*37da2899SCharles.Forsyth /* ELSE */ PACK( 0, 0 ), 891*37da2899SCharles.Forsyth /* JMPR */ PACK( 1, 0 ), 892*37da2899SCharles.Forsyth /* SCvTCi */ PACK( 1, 0 ), 893*37da2899SCharles.Forsyth /* SSwCi */ PACK( 1, 0 ), 894*37da2899SCharles.Forsyth /* SSW */ PACK( 1, 0 ), 895*37da2899SCharles.Forsyth 896*37da2899SCharles.Forsyth /* DUP */ PACK( 1, 2 ), 897*37da2899SCharles.Forsyth /* POP */ PACK( 1, 0 ), 898*37da2899SCharles.Forsyth /* CLEAR */ PACK( 0, 0 ), 899*37da2899SCharles.Forsyth /* SWAP */ PACK( 2, 2 ), 900*37da2899SCharles.Forsyth /* DEPTH */ PACK( 0, 1 ), 901*37da2899SCharles.Forsyth /* CINDEX */ PACK( 1, 1 ), 902*37da2899SCharles.Forsyth /* MINDEX */ PACK( 1, 0 ), 903*37da2899SCharles.Forsyth /* AlignPTS */ PACK( 2, 0 ), 904*37da2899SCharles.Forsyth /* INS_$28 */ PACK( 0, 0 ), 905*37da2899SCharles.Forsyth /* UTP */ PACK( 1, 0 ), 906*37da2899SCharles.Forsyth /* LOOPCALL */ PACK( 2, 0 ), 907*37da2899SCharles.Forsyth /* CALL */ PACK( 1, 0 ), 908*37da2899SCharles.Forsyth /* FDEF */ PACK( 1, 0 ), 909*37da2899SCharles.Forsyth /* ENDF */ PACK( 0, 0 ), 910*37da2899SCharles.Forsyth /* MDAP[0] */ PACK( 1, 0 ), 911*37da2899SCharles.Forsyth /* MDAP[1] */ PACK( 1, 0 ), 912*37da2899SCharles.Forsyth 913*37da2899SCharles.Forsyth /* IUP[0] */ PACK( 0, 0 ), 914*37da2899SCharles.Forsyth /* IUP[1] */ PACK( 0, 0 ), 915*37da2899SCharles.Forsyth /* SHP[0] */ PACK( 0, 0 ), 916*37da2899SCharles.Forsyth /* SHP[1] */ PACK( 0, 0 ), 917*37da2899SCharles.Forsyth /* SHC[0] */ PACK( 1, 0 ), 918*37da2899SCharles.Forsyth /* SHC[1] */ PACK( 1, 0 ), 919*37da2899SCharles.Forsyth /* SHZ[0] */ PACK( 1, 0 ), 920*37da2899SCharles.Forsyth /* SHZ[1] */ PACK( 1, 0 ), 921*37da2899SCharles.Forsyth /* SHPIX */ PACK( 1, 0 ), 922*37da2899SCharles.Forsyth /* IP */ PACK( 0, 0 ), 923*37da2899SCharles.Forsyth /* MSIRP[0] */ PACK( 2, 0 ), 924*37da2899SCharles.Forsyth /* MSIRP[1] */ PACK( 2, 0 ), 925*37da2899SCharles.Forsyth /* AlignRP */ PACK( 0, 0 ), 926*37da2899SCharles.Forsyth /* RTDG */ PACK( 0, 0 ), 927*37da2899SCharles.Forsyth /* MIAP[0] */ PACK( 2, 0 ), 928*37da2899SCharles.Forsyth /* MIAP[1] */ PACK( 2, 0 ), 929*37da2899SCharles.Forsyth 930*37da2899SCharles.Forsyth /* NPushB */ PACK( 0, 0 ), 931*37da2899SCharles.Forsyth /* NPushW */ PACK( 0, 0 ), 932*37da2899SCharles.Forsyth /* WS */ PACK( 2, 0 ), 933*37da2899SCharles.Forsyth /* RS */ PACK( 1, 1 ), 934*37da2899SCharles.Forsyth /* WCvtP */ PACK( 2, 0 ), 935*37da2899SCharles.Forsyth /* RCvt */ PACK( 1, 1 ), 936*37da2899SCharles.Forsyth /* GC[0] */ PACK( 1, 1 ), 937*37da2899SCharles.Forsyth /* GC[1] */ PACK( 1, 1 ), 938*37da2899SCharles.Forsyth /* SCFS */ PACK( 2, 0 ), 939*37da2899SCharles.Forsyth /* MD[0] */ PACK( 2, 1 ), 940*37da2899SCharles.Forsyth /* MD[1] */ PACK( 2, 1 ), 941*37da2899SCharles.Forsyth /* MPPEM */ PACK( 0, 1 ), 942*37da2899SCharles.Forsyth /* MPS */ PACK( 0, 1 ), 943*37da2899SCharles.Forsyth /* FlipON */ PACK( 0, 0 ), 944*37da2899SCharles.Forsyth /* FlipOFF */ PACK( 0, 0 ), 945*37da2899SCharles.Forsyth /* DEBUG */ PACK( 1, 0 ), 946*37da2899SCharles.Forsyth 947*37da2899SCharles.Forsyth /* LT */ PACK( 2, 1 ), 948*37da2899SCharles.Forsyth /* LTEQ */ PACK( 2, 1 ), 949*37da2899SCharles.Forsyth /* GT */ PACK( 2, 1 ), 950*37da2899SCharles.Forsyth /* GTEQ */ PACK( 2, 1 ), 951*37da2899SCharles.Forsyth /* EQ */ PACK( 2, 1 ), 952*37da2899SCharles.Forsyth /* NEQ */ PACK( 2, 1 ), 953*37da2899SCharles.Forsyth /* ODD */ PACK( 1, 1 ), 954*37da2899SCharles.Forsyth /* EVEN */ PACK( 1, 1 ), 955*37da2899SCharles.Forsyth /* IF */ PACK( 1, 0 ), 956*37da2899SCharles.Forsyth /* EIF */ PACK( 0, 0 ), 957*37da2899SCharles.Forsyth /* AND */ PACK( 2, 1 ), 958*37da2899SCharles.Forsyth /* OR */ PACK( 2, 1 ), 959*37da2899SCharles.Forsyth /* NOT */ PACK( 1, 1 ), 960*37da2899SCharles.Forsyth /* DeltaP1 */ PACK( 1, 0 ), 961*37da2899SCharles.Forsyth /* SDB */ PACK( 1, 0 ), 962*37da2899SCharles.Forsyth /* SDS */ PACK( 1, 0 ), 963*37da2899SCharles.Forsyth 964*37da2899SCharles.Forsyth /* ADD */ PACK( 2, 1 ), 965*37da2899SCharles.Forsyth /* SUB */ PACK( 2, 1 ), 966*37da2899SCharles.Forsyth /* DIV */ PACK( 2, 1 ), 967*37da2899SCharles.Forsyth /* MUL */ PACK( 2, 1 ), 968*37da2899SCharles.Forsyth /* ABS */ PACK( 1, 1 ), 969*37da2899SCharles.Forsyth /* NEG */ PACK( 1, 1 ), 970*37da2899SCharles.Forsyth /* FLOOR */ PACK( 1, 1 ), 971*37da2899SCharles.Forsyth /* CEILING */ PACK( 1, 1 ), 972*37da2899SCharles.Forsyth /* ROUND[0] */ PACK( 1, 1 ), 973*37da2899SCharles.Forsyth /* ROUND[1] */ PACK( 1, 1 ), 974*37da2899SCharles.Forsyth /* ROUND[2] */ PACK( 1, 1 ), 975*37da2899SCharles.Forsyth /* ROUND[3] */ PACK( 1, 1 ), 976*37da2899SCharles.Forsyth /* NROUND[0] */ PACK( 1, 1 ), 977*37da2899SCharles.Forsyth /* NROUND[1] */ PACK( 1, 1 ), 978*37da2899SCharles.Forsyth /* NROUND[2] */ PACK( 1, 1 ), 979*37da2899SCharles.Forsyth /* NROUND[3] */ PACK( 1, 1 ), 980*37da2899SCharles.Forsyth 981*37da2899SCharles.Forsyth /* WCvtF */ PACK( 2, 0 ), 982*37da2899SCharles.Forsyth /* DeltaP2 */ PACK( 1, 0 ), 983*37da2899SCharles.Forsyth /* DeltaP3 */ PACK( 1, 0 ), 984*37da2899SCharles.Forsyth /* DeltaCn[0] */ PACK( 1, 0 ), 985*37da2899SCharles.Forsyth /* DeltaCn[1] */ PACK( 1, 0 ), 986*37da2899SCharles.Forsyth /* DeltaCn[2] */ PACK( 1, 0 ), 987*37da2899SCharles.Forsyth /* SROUND */ PACK( 1, 0 ), 988*37da2899SCharles.Forsyth /* S45Round */ PACK( 1, 0 ), 989*37da2899SCharles.Forsyth /* JROT */ PACK( 2, 0 ), 990*37da2899SCharles.Forsyth /* JROF */ PACK( 2, 0 ), 991*37da2899SCharles.Forsyth /* ROFF */ PACK( 0, 0 ), 992*37da2899SCharles.Forsyth /* INS_$7B */ PACK( 0, 0 ), 993*37da2899SCharles.Forsyth /* RUTG */ PACK( 0, 0 ), 994*37da2899SCharles.Forsyth /* RDTG */ PACK( 0, 0 ), 995*37da2899SCharles.Forsyth /* SANGW */ PACK( 1, 0 ), 996*37da2899SCharles.Forsyth /* AA */ PACK( 1, 0 ), 997*37da2899SCharles.Forsyth 998*37da2899SCharles.Forsyth /* FlipPT */ PACK( 0, 0 ), 999*37da2899SCharles.Forsyth /* FlipRgON */ PACK( 2, 0 ), 1000*37da2899SCharles.Forsyth /* FlipRgOFF */ PACK( 2, 0 ), 1001*37da2899SCharles.Forsyth /* INS_$83 */ PACK( 0, 0 ), 1002*37da2899SCharles.Forsyth /* INS_$84 */ PACK( 0, 0 ), 1003*37da2899SCharles.Forsyth /* ScanCTRL */ PACK( 1, 0 ), 1004*37da2899SCharles.Forsyth /* SDVPTL[0] */ PACK( 2, 0 ), 1005*37da2899SCharles.Forsyth /* SDVPTL[1] */ PACK( 2, 0 ), 1006*37da2899SCharles.Forsyth /* GetINFO */ PACK( 1, 1 ), 1007*37da2899SCharles.Forsyth /* IDEF */ PACK( 1, 0 ), 1008*37da2899SCharles.Forsyth /* ROLL */ PACK( 3, 3 ), 1009*37da2899SCharles.Forsyth /* MAX */ PACK( 2, 1 ), 1010*37da2899SCharles.Forsyth /* MIN */ PACK( 2, 1 ), 1011*37da2899SCharles.Forsyth /* ScanTYPE */ PACK( 1, 0 ), 1012*37da2899SCharles.Forsyth /* InstCTRL */ PACK( 2, 0 ), 1013*37da2899SCharles.Forsyth /* INS_$8F */ PACK( 0, 0 ), 1014*37da2899SCharles.Forsyth 1015*37da2899SCharles.Forsyth /* INS_$90 */ PACK( 0, 0 ), 1016*37da2899SCharles.Forsyth /* INS_$91 */ PACK( 0, 0 ), 1017*37da2899SCharles.Forsyth /* INS_$92 */ PACK( 0, 0 ), 1018*37da2899SCharles.Forsyth /* INS_$93 */ PACK( 0, 0 ), 1019*37da2899SCharles.Forsyth /* INS_$94 */ PACK( 0, 0 ), 1020*37da2899SCharles.Forsyth /* INS_$95 */ PACK( 0, 0 ), 1021*37da2899SCharles.Forsyth /* INS_$96 */ PACK( 0, 0 ), 1022*37da2899SCharles.Forsyth /* INS_$97 */ PACK( 0, 0 ), 1023*37da2899SCharles.Forsyth /* INS_$98 */ PACK( 0, 0 ), 1024*37da2899SCharles.Forsyth /* INS_$99 */ PACK( 0, 0 ), 1025*37da2899SCharles.Forsyth /* INS_$9A */ PACK( 0, 0 ), 1026*37da2899SCharles.Forsyth /* INS_$9B */ PACK( 0, 0 ), 1027*37da2899SCharles.Forsyth /* INS_$9C */ PACK( 0, 0 ), 1028*37da2899SCharles.Forsyth /* INS_$9D */ PACK( 0, 0 ), 1029*37da2899SCharles.Forsyth /* INS_$9E */ PACK( 0, 0 ), 1030*37da2899SCharles.Forsyth /* INS_$9F */ PACK( 0, 0 ), 1031*37da2899SCharles.Forsyth 1032*37da2899SCharles.Forsyth /* INS_$A0 */ PACK( 0, 0 ), 1033*37da2899SCharles.Forsyth /* INS_$A1 */ PACK( 0, 0 ), 1034*37da2899SCharles.Forsyth /* INS_$A2 */ PACK( 0, 0 ), 1035*37da2899SCharles.Forsyth /* INS_$A3 */ PACK( 0, 0 ), 1036*37da2899SCharles.Forsyth /* INS_$A4 */ PACK( 0, 0 ), 1037*37da2899SCharles.Forsyth /* INS_$A5 */ PACK( 0, 0 ), 1038*37da2899SCharles.Forsyth /* INS_$A6 */ PACK( 0, 0 ), 1039*37da2899SCharles.Forsyth /* INS_$A7 */ PACK( 0, 0 ), 1040*37da2899SCharles.Forsyth /* INS_$A8 */ PACK( 0, 0 ), 1041*37da2899SCharles.Forsyth /* INS_$A9 */ PACK( 0, 0 ), 1042*37da2899SCharles.Forsyth /* INS_$AA */ PACK( 0, 0 ), 1043*37da2899SCharles.Forsyth /* INS_$AB */ PACK( 0, 0 ), 1044*37da2899SCharles.Forsyth /* INS_$AC */ PACK( 0, 0 ), 1045*37da2899SCharles.Forsyth /* INS_$AD */ PACK( 0, 0 ), 1046*37da2899SCharles.Forsyth /* INS_$AE */ PACK( 0, 0 ), 1047*37da2899SCharles.Forsyth /* INS_$AF */ PACK( 0, 0 ), 1048*37da2899SCharles.Forsyth 1049*37da2899SCharles.Forsyth /* PushB[0] */ PACK( 0, 1 ), 1050*37da2899SCharles.Forsyth /* PushB[1] */ PACK( 0, 2 ), 1051*37da2899SCharles.Forsyth /* PushB[2] */ PACK( 0, 3 ), 1052*37da2899SCharles.Forsyth /* PushB[3] */ PACK( 0, 4 ), 1053*37da2899SCharles.Forsyth /* PushB[4] */ PACK( 0, 5 ), 1054*37da2899SCharles.Forsyth /* PushB[5] */ PACK( 0, 6 ), 1055*37da2899SCharles.Forsyth /* PushB[6] */ PACK( 0, 7 ), 1056*37da2899SCharles.Forsyth /* PushB[7] */ PACK( 0, 8 ), 1057*37da2899SCharles.Forsyth /* PushW[0] */ PACK( 0, 1 ), 1058*37da2899SCharles.Forsyth /* PushW[1] */ PACK( 0, 2 ), 1059*37da2899SCharles.Forsyth /* PushW[2] */ PACK( 0, 3 ), 1060*37da2899SCharles.Forsyth /* PushW[3] */ PACK( 0, 4 ), 1061*37da2899SCharles.Forsyth /* PushW[4] */ PACK( 0, 5 ), 1062*37da2899SCharles.Forsyth /* PushW[5] */ PACK( 0, 6 ), 1063*37da2899SCharles.Forsyth /* PushW[6] */ PACK( 0, 7 ), 1064*37da2899SCharles.Forsyth /* PushW[7] */ PACK( 0, 8 ), 1065*37da2899SCharles.Forsyth 1066*37da2899SCharles.Forsyth /* MDRP[00] */ PACK( 1, 0 ), 1067*37da2899SCharles.Forsyth /* MDRP[01] */ PACK( 1, 0 ), 1068*37da2899SCharles.Forsyth /* MDRP[02] */ PACK( 1, 0 ), 1069*37da2899SCharles.Forsyth /* MDRP[03] */ PACK( 1, 0 ), 1070*37da2899SCharles.Forsyth /* MDRP[04] */ PACK( 1, 0 ), 1071*37da2899SCharles.Forsyth /* MDRP[05] */ PACK( 1, 0 ), 1072*37da2899SCharles.Forsyth /* MDRP[06] */ PACK( 1, 0 ), 1073*37da2899SCharles.Forsyth /* MDRP[07] */ PACK( 1, 0 ), 1074*37da2899SCharles.Forsyth /* MDRP[08] */ PACK( 1, 0 ), 1075*37da2899SCharles.Forsyth /* MDRP[09] */ PACK( 1, 0 ), 1076*37da2899SCharles.Forsyth /* MDRP[10] */ PACK( 1, 0 ), 1077*37da2899SCharles.Forsyth /* MDRP[11] */ PACK( 1, 0 ), 1078*37da2899SCharles.Forsyth /* MDRP[12] */ PACK( 1, 0 ), 1079*37da2899SCharles.Forsyth /* MDRP[13] */ PACK( 1, 0 ), 1080*37da2899SCharles.Forsyth /* MDRP[14] */ PACK( 1, 0 ), 1081*37da2899SCharles.Forsyth /* MDRP[15] */ PACK( 1, 0 ), 1082*37da2899SCharles.Forsyth 1083*37da2899SCharles.Forsyth /* MDRP[16] */ PACK( 1, 0 ), 1084*37da2899SCharles.Forsyth /* MDRP[17] */ PACK( 1, 0 ), 1085*37da2899SCharles.Forsyth /* MDRP[18] */ PACK( 1, 0 ), 1086*37da2899SCharles.Forsyth /* MDRP[19] */ PACK( 1, 0 ), 1087*37da2899SCharles.Forsyth /* MDRP[20] */ PACK( 1, 0 ), 1088*37da2899SCharles.Forsyth /* MDRP[21] */ PACK( 1, 0 ), 1089*37da2899SCharles.Forsyth /* MDRP[22] */ PACK( 1, 0 ), 1090*37da2899SCharles.Forsyth /* MDRP[23] */ PACK( 1, 0 ), 1091*37da2899SCharles.Forsyth /* MDRP[24] */ PACK( 1, 0 ), 1092*37da2899SCharles.Forsyth /* MDRP[25] */ PACK( 1, 0 ), 1093*37da2899SCharles.Forsyth /* MDRP[26] */ PACK( 1, 0 ), 1094*37da2899SCharles.Forsyth /* MDRP[27] */ PACK( 1, 0 ), 1095*37da2899SCharles.Forsyth /* MDRP[28] */ PACK( 1, 0 ), 1096*37da2899SCharles.Forsyth /* MDRP[29] */ PACK( 1, 0 ), 1097*37da2899SCharles.Forsyth /* MDRP[30] */ PACK( 1, 0 ), 1098*37da2899SCharles.Forsyth /* MDRP[31] */ PACK( 1, 0 ), 1099*37da2899SCharles.Forsyth 1100*37da2899SCharles.Forsyth /* MIRP[00] */ PACK( 2, 0 ), 1101*37da2899SCharles.Forsyth /* MIRP[01] */ PACK( 2, 0 ), 1102*37da2899SCharles.Forsyth /* MIRP[02] */ PACK( 2, 0 ), 1103*37da2899SCharles.Forsyth /* MIRP[03] */ PACK( 2, 0 ), 1104*37da2899SCharles.Forsyth /* MIRP[04] */ PACK( 2, 0 ), 1105*37da2899SCharles.Forsyth /* MIRP[05] */ PACK( 2, 0 ), 1106*37da2899SCharles.Forsyth /* MIRP[06] */ PACK( 2, 0 ), 1107*37da2899SCharles.Forsyth /* MIRP[07] */ PACK( 2, 0 ), 1108*37da2899SCharles.Forsyth /* MIRP[08] */ PACK( 2, 0 ), 1109*37da2899SCharles.Forsyth /* MIRP[09] */ PACK( 2, 0 ), 1110*37da2899SCharles.Forsyth /* MIRP[10] */ PACK( 2, 0 ), 1111*37da2899SCharles.Forsyth /* MIRP[11] */ PACK( 2, 0 ), 1112*37da2899SCharles.Forsyth /* MIRP[12] */ PACK( 2, 0 ), 1113*37da2899SCharles.Forsyth /* MIRP[13] */ PACK( 2, 0 ), 1114*37da2899SCharles.Forsyth /* MIRP[14] */ PACK( 2, 0 ), 1115*37da2899SCharles.Forsyth /* MIRP[15] */ PACK( 2, 0 ), 1116*37da2899SCharles.Forsyth 1117*37da2899SCharles.Forsyth /* MIRP[16] */ PACK( 2, 0 ), 1118*37da2899SCharles.Forsyth /* MIRP[17] */ PACK( 2, 0 ), 1119*37da2899SCharles.Forsyth /* MIRP[18] */ PACK( 2, 0 ), 1120*37da2899SCharles.Forsyth /* MIRP[19] */ PACK( 2, 0 ), 1121*37da2899SCharles.Forsyth /* MIRP[20] */ PACK( 2, 0 ), 1122*37da2899SCharles.Forsyth /* MIRP[21] */ PACK( 2, 0 ), 1123*37da2899SCharles.Forsyth /* MIRP[22] */ PACK( 2, 0 ), 1124*37da2899SCharles.Forsyth /* MIRP[23] */ PACK( 2, 0 ), 1125*37da2899SCharles.Forsyth /* MIRP[24] */ PACK( 2, 0 ), 1126*37da2899SCharles.Forsyth /* MIRP[25] */ PACK( 2, 0 ), 1127*37da2899SCharles.Forsyth /* MIRP[26] */ PACK( 2, 0 ), 1128*37da2899SCharles.Forsyth /* MIRP[27] */ PACK( 2, 0 ), 1129*37da2899SCharles.Forsyth /* MIRP[28] */ PACK( 2, 0 ), 1130*37da2899SCharles.Forsyth /* MIRP[29] */ PACK( 2, 0 ), 1131*37da2899SCharles.Forsyth /* MIRP[30] */ PACK( 2, 0 ), 1132*37da2899SCharles.Forsyth /* MIRP[31] */ PACK( 2, 0 ) 1133*37da2899SCharles.Forsyth }; 1134*37da2899SCharles.Forsyth 1135*37da2899SCharles.Forsyth 1136*37da2899SCharles.Forsyth static 1137*37da2899SCharles.Forsyth const FT_Char opcode_length[256] = 1138*37da2899SCharles.Forsyth { 1139*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1140*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1141*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1142*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1143*37da2899SCharles.Forsyth 1144*37da2899SCharles.Forsyth -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1145*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1146*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1147*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1148*37da2899SCharles.Forsyth 1149*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1150*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1151*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1152*37da2899SCharles.Forsyth 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, 1153*37da2899SCharles.Forsyth 1154*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1155*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1156*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1157*37da2899SCharles.Forsyth 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1158*37da2899SCharles.Forsyth }; 1159*37da2899SCharles.Forsyth 1160*37da2899SCharles.Forsyth static 1161*37da2899SCharles.Forsyth const FT_Vector Null_Vector = {0,0}; 1162*37da2899SCharles.Forsyth 1163*37da2899SCharles.Forsyth 1164*37da2899SCharles.Forsyth #undef PACK 1165*37da2899SCharles.Forsyth 1166*37da2899SCharles.Forsyth 1167*37da2899SCharles.Forsyth #undef NULL_Vector 1168*37da2899SCharles.Forsyth #define NULL_Vector (FT_Vector*)&Null_Vector 1169*37da2899SCharles.Forsyth 1170*37da2899SCharles.Forsyth 1171*37da2899SCharles.Forsyth /* compute (a*b)/2^14 with maximal accuracy and rounding */ 1172*37da2899SCharles.Forsyth static FT_Int32 TT_MulFix14(FT_Int32 a,FT_Int b)1173*37da2899SCharles.Forsyth TT_MulFix14( FT_Int32 a, 1174*37da2899SCharles.Forsyth FT_Int b ) 1175*37da2899SCharles.Forsyth { 1176*37da2899SCharles.Forsyth FT_Int32 m, s, hi; 1177*37da2899SCharles.Forsyth FT_UInt32 l, lo; 1178*37da2899SCharles.Forsyth 1179*37da2899SCharles.Forsyth 1180*37da2899SCharles.Forsyth /* compute ax*bx as 64-bit value */ 1181*37da2899SCharles.Forsyth l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); 1182*37da2899SCharles.Forsyth m = ( a >> 16 ) * b; 1183*37da2899SCharles.Forsyth 1184*37da2899SCharles.Forsyth lo = l + (FT_UInt32)( m << 16 ); 1185*37da2899SCharles.Forsyth hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); 1186*37da2899SCharles.Forsyth 1187*37da2899SCharles.Forsyth /* divide the result by 2^14 with rounding */ 1188*37da2899SCharles.Forsyth s = hi >> 31; 1189*37da2899SCharles.Forsyth l = lo + (FT_UInt32)s; 1190*37da2899SCharles.Forsyth hi += s + ( l < lo ); 1191*37da2899SCharles.Forsyth lo = l; 1192*37da2899SCharles.Forsyth 1193*37da2899SCharles.Forsyth l = lo + 0x2000U; 1194*37da2899SCharles.Forsyth hi += (l < lo); 1195*37da2899SCharles.Forsyth 1196*37da2899SCharles.Forsyth return ( hi << 18 ) | ( l >> 14 ); 1197*37da2899SCharles.Forsyth } 1198*37da2899SCharles.Forsyth 1199*37da2899SCharles.Forsyth 1200*37da2899SCharles.Forsyth /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */ 1201*37da2899SCharles.Forsyth static FT_Int32 TT_DotFix14(FT_Int32 ax,FT_Int32 ay,FT_Int bx,FT_Int by)1202*37da2899SCharles.Forsyth TT_DotFix14( FT_Int32 ax, 1203*37da2899SCharles.Forsyth FT_Int32 ay, 1204*37da2899SCharles.Forsyth FT_Int bx, 1205*37da2899SCharles.Forsyth FT_Int by ) 1206*37da2899SCharles.Forsyth { 1207*37da2899SCharles.Forsyth FT_Int32 m, s, hi1, hi2, hi; 1208*37da2899SCharles.Forsyth FT_UInt32 l, lo1, lo2, lo; 1209*37da2899SCharles.Forsyth 1210*37da2899SCharles.Forsyth 1211*37da2899SCharles.Forsyth /* compute ax*bx as 64-bit value */ 1212*37da2899SCharles.Forsyth l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); 1213*37da2899SCharles.Forsyth m = ( ax >> 16 ) * bx; 1214*37da2899SCharles.Forsyth 1215*37da2899SCharles.Forsyth lo1 = l + (FT_UInt32)( m << 16 ); 1216*37da2899SCharles.Forsyth hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); 1217*37da2899SCharles.Forsyth 1218*37da2899SCharles.Forsyth /* compute ay*by as 64-bit value */ 1219*37da2899SCharles.Forsyth l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); 1220*37da2899SCharles.Forsyth m = ( ay >> 16 ) * by; 1221*37da2899SCharles.Forsyth 1222*37da2899SCharles.Forsyth lo2 = l + (FT_UInt32)( m << 16 ); 1223*37da2899SCharles.Forsyth hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); 1224*37da2899SCharles.Forsyth 1225*37da2899SCharles.Forsyth /* add them */ 1226*37da2899SCharles.Forsyth lo = lo1 + lo2; 1227*37da2899SCharles.Forsyth hi = hi1 + hi2 + ( lo < lo1 ); 1228*37da2899SCharles.Forsyth 1229*37da2899SCharles.Forsyth /* divide the result by 2^14 with rounding */ 1230*37da2899SCharles.Forsyth s = hi >> 31; 1231*37da2899SCharles.Forsyth l = lo + (FT_UInt32)s; 1232*37da2899SCharles.Forsyth hi += s + ( l < lo ); 1233*37da2899SCharles.Forsyth lo = l; 1234*37da2899SCharles.Forsyth 1235*37da2899SCharles.Forsyth l = lo + 0x2000U; 1236*37da2899SCharles.Forsyth hi += ( l < lo ); 1237*37da2899SCharles.Forsyth 1238*37da2899SCharles.Forsyth return ( hi << 18 ) | ( l >> 14 ); 1239*37da2899SCharles.Forsyth } 1240*37da2899SCharles.Forsyth 1241*37da2899SCharles.Forsyth 1242*37da2899SCharles.Forsyth /* return length of given vector */ 1243*37da2899SCharles.Forsyth 1244*37da2899SCharles.Forsyth #if 0 1245*37da2899SCharles.Forsyth 1246*37da2899SCharles.Forsyth static FT_Int32 1247*37da2899SCharles.Forsyth TT_VecLen( FT_Int32 x, 1248*37da2899SCharles.Forsyth FT_Int32 y ) 1249*37da2899SCharles.Forsyth { 1250*37da2899SCharles.Forsyth FT_Int32 m, hi1, hi2, hi; 1251*37da2899SCharles.Forsyth FT_UInt32 l, lo1, lo2, lo; 1252*37da2899SCharles.Forsyth 1253*37da2899SCharles.Forsyth 1254*37da2899SCharles.Forsyth /* compute x*x as 64-bit value */ 1255*37da2899SCharles.Forsyth lo = (FT_UInt32)( x & 0xFFFFU ); 1256*37da2899SCharles.Forsyth hi = x >> 16; 1257*37da2899SCharles.Forsyth 1258*37da2899SCharles.Forsyth l = lo * lo; 1259*37da2899SCharles.Forsyth m = hi * lo; 1260*37da2899SCharles.Forsyth hi = hi * hi; 1261*37da2899SCharles.Forsyth 1262*37da2899SCharles.Forsyth lo1 = l + (FT_UInt32)( m << 17 ); 1263*37da2899SCharles.Forsyth hi1 = hi + ( m >> 15 ) + ( lo1 < l ); 1264*37da2899SCharles.Forsyth 1265*37da2899SCharles.Forsyth /* compute y*y as 64-bit value */ 1266*37da2899SCharles.Forsyth lo = (FT_UInt32)( y & 0xFFFFU ); 1267*37da2899SCharles.Forsyth hi = y >> 16; 1268*37da2899SCharles.Forsyth 1269*37da2899SCharles.Forsyth l = lo * lo; 1270*37da2899SCharles.Forsyth m = hi * lo; 1271*37da2899SCharles.Forsyth hi = hi * hi; 1272*37da2899SCharles.Forsyth 1273*37da2899SCharles.Forsyth lo2 = l + (FT_UInt32)( m << 17 ); 1274*37da2899SCharles.Forsyth hi2 = hi + ( m >> 15 ) + ( lo2 < l ); 1275*37da2899SCharles.Forsyth 1276*37da2899SCharles.Forsyth /* add them to get 'x*x+y*y' as 64-bit value */ 1277*37da2899SCharles.Forsyth lo = lo1 + lo2; 1278*37da2899SCharles.Forsyth hi = hi1 + hi2 + ( lo < lo1 ); 1279*37da2899SCharles.Forsyth 1280*37da2899SCharles.Forsyth /* compute the square root of this value */ 1281*37da2899SCharles.Forsyth { 1282*37da2899SCharles.Forsyth FT_UInt32 root, rem, test_div; 1283*37da2899SCharles.Forsyth FT_Int count; 1284*37da2899SCharles.Forsyth 1285*37da2899SCharles.Forsyth 1286*37da2899SCharles.Forsyth root = 0; 1287*37da2899SCharles.Forsyth 1288*37da2899SCharles.Forsyth { 1289*37da2899SCharles.Forsyth rem = 0; 1290*37da2899SCharles.Forsyth count = 32; 1291*37da2899SCharles.Forsyth do 1292*37da2899SCharles.Forsyth { 1293*37da2899SCharles.Forsyth rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 ); 1294*37da2899SCharles.Forsyth hi = ( hi << 2 ) | ( lo >> 30 ); 1295*37da2899SCharles.Forsyth lo <<= 2; 1296*37da2899SCharles.Forsyth root <<= 1; 1297*37da2899SCharles.Forsyth test_div = ( root << 1 ) + 1; 1298*37da2899SCharles.Forsyth 1299*37da2899SCharles.Forsyth if ( rem >= test_div ) 1300*37da2899SCharles.Forsyth { 1301*37da2899SCharles.Forsyth rem -= test_div; 1302*37da2899SCharles.Forsyth root += 1; 1303*37da2899SCharles.Forsyth } 1304*37da2899SCharles.Forsyth } while ( --count ); 1305*37da2899SCharles.Forsyth } 1306*37da2899SCharles.Forsyth 1307*37da2899SCharles.Forsyth return (FT_Int32)root; 1308*37da2899SCharles.Forsyth } 1309*37da2899SCharles.Forsyth } 1310*37da2899SCharles.Forsyth 1311*37da2899SCharles.Forsyth #else 1312*37da2899SCharles.Forsyth 1313*37da2899SCharles.Forsyth /* this version uses FT_Vector_Length which computes the same value */ 1314*37da2899SCharles.Forsyth /* much, much faster.. */ 1315*37da2899SCharles.Forsyth /* */ 1316*37da2899SCharles.Forsyth static FT_F26Dot6 TT_VecLen(FT_F26Dot6 X,FT_F26Dot6 Y)1317*37da2899SCharles.Forsyth TT_VecLen( FT_F26Dot6 X, 1318*37da2899SCharles.Forsyth FT_F26Dot6 Y ) 1319*37da2899SCharles.Forsyth { 1320*37da2899SCharles.Forsyth FT_Vector v; 1321*37da2899SCharles.Forsyth 1322*37da2899SCharles.Forsyth 1323*37da2899SCharles.Forsyth v.x = X; 1324*37da2899SCharles.Forsyth v.y = Y; 1325*37da2899SCharles.Forsyth 1326*37da2899SCharles.Forsyth return FT_Vector_Length( &v ); 1327*37da2899SCharles.Forsyth } 1328*37da2899SCharles.Forsyth 1329*37da2899SCharles.Forsyth #endif 1330*37da2899SCharles.Forsyth 1331*37da2899SCharles.Forsyth 1332*37da2899SCharles.Forsyth /*************************************************************************/ 1333*37da2899SCharles.Forsyth /* */ 1334*37da2899SCharles.Forsyth /* <Function> */ 1335*37da2899SCharles.Forsyth /* Current_Ratio */ 1336*37da2899SCharles.Forsyth /* */ 1337*37da2899SCharles.Forsyth /* <Description> */ 1338*37da2899SCharles.Forsyth /* Returns the current aspect ratio scaling factor depending on the */ 1339*37da2899SCharles.Forsyth /* projection vector's state and device resolutions. */ 1340*37da2899SCharles.Forsyth /* */ 1341*37da2899SCharles.Forsyth /* <Return> */ 1342*37da2899SCharles.Forsyth /* The aspect ratio in 16.16 format, always <= 1.0 . */ 1343*37da2899SCharles.Forsyth /* */ 1344*37da2899SCharles.Forsyth static FT_Long Current_Ratio(EXEC_OP)1345*37da2899SCharles.Forsyth Current_Ratio( EXEC_OP ) 1346*37da2899SCharles.Forsyth { 1347*37da2899SCharles.Forsyth if ( CUR.tt_metrics.ratio ) 1348*37da2899SCharles.Forsyth return CUR.tt_metrics.ratio; 1349*37da2899SCharles.Forsyth 1350*37da2899SCharles.Forsyth if ( CUR.GS.projVector.y == 0 ) 1351*37da2899SCharles.Forsyth CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; 1352*37da2899SCharles.Forsyth 1353*37da2899SCharles.Forsyth else if ( CUR.GS.projVector.x == 0 ) 1354*37da2899SCharles.Forsyth CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; 1355*37da2899SCharles.Forsyth 1356*37da2899SCharles.Forsyth else 1357*37da2899SCharles.Forsyth { 1358*37da2899SCharles.Forsyth FT_Long x, y; 1359*37da2899SCharles.Forsyth 1360*37da2899SCharles.Forsyth x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 ); 1361*37da2899SCharles.Forsyth y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 ); 1362*37da2899SCharles.Forsyth CUR.tt_metrics.ratio = TT_VecLen( x, y ); 1363*37da2899SCharles.Forsyth } 1364*37da2899SCharles.Forsyth 1365*37da2899SCharles.Forsyth return CUR.tt_metrics.ratio; 1366*37da2899SCharles.Forsyth } 1367*37da2899SCharles.Forsyth 1368*37da2899SCharles.Forsyth 1369*37da2899SCharles.Forsyth static FT_Long Current_Ppem(EXEC_OP)1370*37da2899SCharles.Forsyth Current_Ppem( EXEC_OP ) 1371*37da2899SCharles.Forsyth { 1372*37da2899SCharles.Forsyth return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); 1373*37da2899SCharles.Forsyth } 1374*37da2899SCharles.Forsyth 1375*37da2899SCharles.Forsyth 1376*37da2899SCharles.Forsyth /*************************************************************************/ 1377*37da2899SCharles.Forsyth /* */ 1378*37da2899SCharles.Forsyth /* Functions related to the control value table (CVT). */ 1379*37da2899SCharles.Forsyth /* */ 1380*37da2899SCharles.Forsyth /*************************************************************************/ 1381*37da2899SCharles.Forsyth 1382*37da2899SCharles.Forsyth 1383*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_F26Dot6 ) Read_CVT(EXEC_OP_ FT_ULong idx)1384*37da2899SCharles.Forsyth Read_CVT( EXEC_OP_ FT_ULong idx ) 1385*37da2899SCharles.Forsyth { 1386*37da2899SCharles.Forsyth return CUR.cvt[idx]; 1387*37da2899SCharles.Forsyth } 1388*37da2899SCharles.Forsyth 1389*37da2899SCharles.Forsyth 1390*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_F26Dot6 ) Read_CVT_Stretched(EXEC_OP_ FT_ULong idx)1391*37da2899SCharles.Forsyth Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) 1392*37da2899SCharles.Forsyth { 1393*37da2899SCharles.Forsyth return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() ); 1394*37da2899SCharles.Forsyth } 1395*37da2899SCharles.Forsyth 1396*37da2899SCharles.Forsyth 1397*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) Write_CVT(EXEC_OP_ FT_ULong idx,FT_F26Dot6 value)1398*37da2899SCharles.Forsyth Write_CVT( EXEC_OP_ FT_ULong idx, 1399*37da2899SCharles.Forsyth FT_F26Dot6 value ) 1400*37da2899SCharles.Forsyth { 1401*37da2899SCharles.Forsyth CUR.cvt[idx] = value; 1402*37da2899SCharles.Forsyth } 1403*37da2899SCharles.Forsyth 1404*37da2899SCharles.Forsyth 1405*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) Write_CVT_Stretched(EXEC_OP_ FT_ULong idx,FT_F26Dot6 value)1406*37da2899SCharles.Forsyth Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, 1407*37da2899SCharles.Forsyth FT_F26Dot6 value ) 1408*37da2899SCharles.Forsyth { 1409*37da2899SCharles.Forsyth CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); 1410*37da2899SCharles.Forsyth } 1411*37da2899SCharles.Forsyth 1412*37da2899SCharles.Forsyth 1413*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) Move_CVT(EXEC_OP_ FT_ULong idx,FT_F26Dot6 value)1414*37da2899SCharles.Forsyth Move_CVT( EXEC_OP_ FT_ULong idx, 1415*37da2899SCharles.Forsyth FT_F26Dot6 value ) 1416*37da2899SCharles.Forsyth { 1417*37da2899SCharles.Forsyth CUR.cvt[idx] += value; 1418*37da2899SCharles.Forsyth } 1419*37da2899SCharles.Forsyth 1420*37da2899SCharles.Forsyth 1421*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) Move_CVT_Stretched(EXEC_OP_ FT_ULong idx,FT_F26Dot6 value)1422*37da2899SCharles.Forsyth Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, 1423*37da2899SCharles.Forsyth FT_F26Dot6 value ) 1424*37da2899SCharles.Forsyth { 1425*37da2899SCharles.Forsyth CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); 1426*37da2899SCharles.Forsyth } 1427*37da2899SCharles.Forsyth 1428*37da2899SCharles.Forsyth 1429*37da2899SCharles.Forsyth /*************************************************************************/ 1430*37da2899SCharles.Forsyth /* */ 1431*37da2899SCharles.Forsyth /* <Function> */ 1432*37da2899SCharles.Forsyth /* GetShortIns */ 1433*37da2899SCharles.Forsyth /* */ 1434*37da2899SCharles.Forsyth /* <Description> */ 1435*37da2899SCharles.Forsyth /* Returns a short integer taken from the instruction stream at */ 1436*37da2899SCharles.Forsyth /* address IP. */ 1437*37da2899SCharles.Forsyth /* */ 1438*37da2899SCharles.Forsyth /* <Return> */ 1439*37da2899SCharles.Forsyth /* Short read at code[IP]. */ 1440*37da2899SCharles.Forsyth /* */ 1441*37da2899SCharles.Forsyth /* <Note> */ 1442*37da2899SCharles.Forsyth /* This one could become a macro. */ 1443*37da2899SCharles.Forsyth /* */ 1444*37da2899SCharles.Forsyth static FT_Short GetShortIns(EXEC_OP)1445*37da2899SCharles.Forsyth GetShortIns( EXEC_OP ) 1446*37da2899SCharles.Forsyth { 1447*37da2899SCharles.Forsyth /* Reading a byte stream so there is no endianess (DaveP) */ 1448*37da2899SCharles.Forsyth CUR.IP += 2; 1449*37da2899SCharles.Forsyth return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + 1450*37da2899SCharles.Forsyth CUR.code[CUR.IP - 1] ); 1451*37da2899SCharles.Forsyth } 1452*37da2899SCharles.Forsyth 1453*37da2899SCharles.Forsyth 1454*37da2899SCharles.Forsyth /*************************************************************************/ 1455*37da2899SCharles.Forsyth /* */ 1456*37da2899SCharles.Forsyth /* <Function> */ 1457*37da2899SCharles.Forsyth /* Ins_Goto_CodeRange */ 1458*37da2899SCharles.Forsyth /* */ 1459*37da2899SCharles.Forsyth /* <Description> */ 1460*37da2899SCharles.Forsyth /* Goes to a certain code range in the instruction stream. */ 1461*37da2899SCharles.Forsyth /* */ 1462*37da2899SCharles.Forsyth /* <Input> */ 1463*37da2899SCharles.Forsyth /* aRange :: The index of the code range. */ 1464*37da2899SCharles.Forsyth /* */ 1465*37da2899SCharles.Forsyth /* aIP :: The new IP address in the code range. */ 1466*37da2899SCharles.Forsyth /* */ 1467*37da2899SCharles.Forsyth /* <Return> */ 1468*37da2899SCharles.Forsyth /* SUCCESS or FAILURE. */ 1469*37da2899SCharles.Forsyth /* */ 1470*37da2899SCharles.Forsyth static FT_Bool Ins_Goto_CodeRange(EXEC_OP_ FT_Int aRange,FT_ULong aIP)1471*37da2899SCharles.Forsyth Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, 1472*37da2899SCharles.Forsyth FT_ULong aIP ) 1473*37da2899SCharles.Forsyth { 1474*37da2899SCharles.Forsyth TT_CodeRange* range; 1475*37da2899SCharles.Forsyth 1476*37da2899SCharles.Forsyth 1477*37da2899SCharles.Forsyth if ( aRange < 1 || aRange > 3 ) 1478*37da2899SCharles.Forsyth { 1479*37da2899SCharles.Forsyth CUR.error = TT_Err_Bad_Argument; 1480*37da2899SCharles.Forsyth return FAILURE; 1481*37da2899SCharles.Forsyth } 1482*37da2899SCharles.Forsyth 1483*37da2899SCharles.Forsyth range = &CUR.codeRangeTable[aRange - 1]; 1484*37da2899SCharles.Forsyth 1485*37da2899SCharles.Forsyth if ( range->base == NULL ) /* invalid coderange */ 1486*37da2899SCharles.Forsyth { 1487*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_CodeRange; 1488*37da2899SCharles.Forsyth return FAILURE; 1489*37da2899SCharles.Forsyth } 1490*37da2899SCharles.Forsyth 1491*37da2899SCharles.Forsyth /* NOTE: Because the last instruction of a program may be a CALL */ 1492*37da2899SCharles.Forsyth /* which will return to the first byte *after* the code */ 1493*37da2899SCharles.Forsyth /* range, we test for AIP <= Size, instead of AIP < Size. */ 1494*37da2899SCharles.Forsyth 1495*37da2899SCharles.Forsyth if ( aIP > range->size ) 1496*37da2899SCharles.Forsyth { 1497*37da2899SCharles.Forsyth CUR.error = TT_Err_Code_Overflow; 1498*37da2899SCharles.Forsyth return FAILURE; 1499*37da2899SCharles.Forsyth } 1500*37da2899SCharles.Forsyth 1501*37da2899SCharles.Forsyth CUR.code = range->base; 1502*37da2899SCharles.Forsyth CUR.codeSize = range->size; 1503*37da2899SCharles.Forsyth CUR.IP = aIP; 1504*37da2899SCharles.Forsyth CUR.curRange = aRange; 1505*37da2899SCharles.Forsyth 1506*37da2899SCharles.Forsyth return SUCCESS; 1507*37da2899SCharles.Forsyth } 1508*37da2899SCharles.Forsyth 1509*37da2899SCharles.Forsyth 1510*37da2899SCharles.Forsyth /*************************************************************************/ 1511*37da2899SCharles.Forsyth /* */ 1512*37da2899SCharles.Forsyth /* <Function> */ 1513*37da2899SCharles.Forsyth /* Direct_Move */ 1514*37da2899SCharles.Forsyth /* */ 1515*37da2899SCharles.Forsyth /* <Description> */ 1516*37da2899SCharles.Forsyth /* Moves a point by a given distance along the freedom vector. The */ 1517*37da2899SCharles.Forsyth /* point will be `touched'. */ 1518*37da2899SCharles.Forsyth /* */ 1519*37da2899SCharles.Forsyth /* <Input> */ 1520*37da2899SCharles.Forsyth /* point :: The index of the point to move. */ 1521*37da2899SCharles.Forsyth /* */ 1522*37da2899SCharles.Forsyth /* distance :: The distance to apply. */ 1523*37da2899SCharles.Forsyth /* */ 1524*37da2899SCharles.Forsyth /* <InOut> */ 1525*37da2899SCharles.Forsyth /* zone :: The affected glyph zone. */ 1526*37da2899SCharles.Forsyth /* */ 1527*37da2899SCharles.Forsyth static void Direct_Move(EXEC_OP_ TT_GlyphZone zone,FT_UShort point,FT_F26Dot6 distance)1528*37da2899SCharles.Forsyth Direct_Move( EXEC_OP_ TT_GlyphZone zone, 1529*37da2899SCharles.Forsyth FT_UShort point, 1530*37da2899SCharles.Forsyth FT_F26Dot6 distance ) 1531*37da2899SCharles.Forsyth { 1532*37da2899SCharles.Forsyth FT_F26Dot6 v; 1533*37da2899SCharles.Forsyth 1534*37da2899SCharles.Forsyth 1535*37da2899SCharles.Forsyth v = CUR.GS.freeVector.x; 1536*37da2899SCharles.Forsyth 1537*37da2899SCharles.Forsyth if ( v != 0 ) 1538*37da2899SCharles.Forsyth { 1539*37da2899SCharles.Forsyth 1540*37da2899SCharles.Forsyth #ifdef NO_APPLE_PATENT 1541*37da2899SCharles.Forsyth 1542*37da2899SCharles.Forsyth if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) 1543*37da2899SCharles.Forsyth zone->cur[point].x += distance; 1544*37da2899SCharles.Forsyth 1545*37da2899SCharles.Forsyth #else 1546*37da2899SCharles.Forsyth 1547*37da2899SCharles.Forsyth zone->cur[point].x += TT_MULDIV( distance, 1548*37da2899SCharles.Forsyth v * 0x10000L, 1549*37da2899SCharles.Forsyth CUR.F_dot_P ); 1550*37da2899SCharles.Forsyth 1551*37da2899SCharles.Forsyth #endif 1552*37da2899SCharles.Forsyth 1553*37da2899SCharles.Forsyth zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; 1554*37da2899SCharles.Forsyth } 1555*37da2899SCharles.Forsyth 1556*37da2899SCharles.Forsyth v = CUR.GS.freeVector.y; 1557*37da2899SCharles.Forsyth 1558*37da2899SCharles.Forsyth if ( v != 0 ) 1559*37da2899SCharles.Forsyth { 1560*37da2899SCharles.Forsyth 1561*37da2899SCharles.Forsyth #ifdef NO_APPLE_PATENT 1562*37da2899SCharles.Forsyth 1563*37da2899SCharles.Forsyth if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) 1564*37da2899SCharles.Forsyth zone->cur[point].y += distance; 1565*37da2899SCharles.Forsyth 1566*37da2899SCharles.Forsyth #else 1567*37da2899SCharles.Forsyth 1568*37da2899SCharles.Forsyth zone->cur[point].y += TT_MULDIV( distance, 1569*37da2899SCharles.Forsyth v * 0x10000L, 1570*37da2899SCharles.Forsyth CUR.F_dot_P ); 1571*37da2899SCharles.Forsyth 1572*37da2899SCharles.Forsyth #endif 1573*37da2899SCharles.Forsyth 1574*37da2899SCharles.Forsyth zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; 1575*37da2899SCharles.Forsyth } 1576*37da2899SCharles.Forsyth } 1577*37da2899SCharles.Forsyth 1578*37da2899SCharles.Forsyth 1579*37da2899SCharles.Forsyth /*************************************************************************/ 1580*37da2899SCharles.Forsyth /* */ 1581*37da2899SCharles.Forsyth /* Special versions of Direct_Move() */ 1582*37da2899SCharles.Forsyth /* */ 1583*37da2899SCharles.Forsyth /* The following versions are used whenever both vectors are both */ 1584*37da2899SCharles.Forsyth /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ 1585*37da2899SCharles.Forsyth /* */ 1586*37da2899SCharles.Forsyth /*************************************************************************/ 1587*37da2899SCharles.Forsyth 1588*37da2899SCharles.Forsyth 1589*37da2899SCharles.Forsyth static void Direct_Move_X(EXEC_OP_ TT_GlyphZone zone,FT_UShort point,FT_F26Dot6 distance)1590*37da2899SCharles.Forsyth Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, 1591*37da2899SCharles.Forsyth FT_UShort point, 1592*37da2899SCharles.Forsyth FT_F26Dot6 distance ) 1593*37da2899SCharles.Forsyth { 1594*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1595*37da2899SCharles.Forsyth 1596*37da2899SCharles.Forsyth zone->cur[point].x += distance; 1597*37da2899SCharles.Forsyth zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; 1598*37da2899SCharles.Forsyth } 1599*37da2899SCharles.Forsyth 1600*37da2899SCharles.Forsyth 1601*37da2899SCharles.Forsyth static void Direct_Move_Y(EXEC_OP_ TT_GlyphZone zone,FT_UShort point,FT_F26Dot6 distance)1602*37da2899SCharles.Forsyth Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, 1603*37da2899SCharles.Forsyth FT_UShort point, 1604*37da2899SCharles.Forsyth FT_F26Dot6 distance ) 1605*37da2899SCharles.Forsyth { 1606*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1607*37da2899SCharles.Forsyth 1608*37da2899SCharles.Forsyth zone->cur[point].y += distance; 1609*37da2899SCharles.Forsyth zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; 1610*37da2899SCharles.Forsyth } 1611*37da2899SCharles.Forsyth 1612*37da2899SCharles.Forsyth 1613*37da2899SCharles.Forsyth /*************************************************************************/ 1614*37da2899SCharles.Forsyth /* */ 1615*37da2899SCharles.Forsyth /* <Function> */ 1616*37da2899SCharles.Forsyth /* Round_None */ 1617*37da2899SCharles.Forsyth /* */ 1618*37da2899SCharles.Forsyth /* <Description> */ 1619*37da2899SCharles.Forsyth /* Does not round, but adds engine compensation. */ 1620*37da2899SCharles.Forsyth /* */ 1621*37da2899SCharles.Forsyth /* <Input> */ 1622*37da2899SCharles.Forsyth /* distance :: The distance (not) to round. */ 1623*37da2899SCharles.Forsyth /* */ 1624*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1625*37da2899SCharles.Forsyth /* */ 1626*37da2899SCharles.Forsyth /* <Return> */ 1627*37da2899SCharles.Forsyth /* The compensated distance. */ 1628*37da2899SCharles.Forsyth /* */ 1629*37da2899SCharles.Forsyth /* <Note> */ 1630*37da2899SCharles.Forsyth /* The TrueType specification says very few about the relationship */ 1631*37da2899SCharles.Forsyth /* between rounding and engine compensation. However, it seems from */ 1632*37da2899SCharles.Forsyth /* the description of super round that we should add the compensation */ 1633*37da2899SCharles.Forsyth /* before rounding. */ 1634*37da2899SCharles.Forsyth /* */ 1635*37da2899SCharles.Forsyth static FT_F26Dot6 Round_None(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1636*37da2899SCharles.Forsyth Round_None( EXEC_OP_ FT_F26Dot6 distance, 1637*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1638*37da2899SCharles.Forsyth { 1639*37da2899SCharles.Forsyth FT_F26Dot6 val; 1640*37da2899SCharles.Forsyth 1641*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1642*37da2899SCharles.Forsyth 1643*37da2899SCharles.Forsyth 1644*37da2899SCharles.Forsyth if ( distance >= 0 ) 1645*37da2899SCharles.Forsyth { 1646*37da2899SCharles.Forsyth val = distance + compensation; 1647*37da2899SCharles.Forsyth if ( val < 0 ) 1648*37da2899SCharles.Forsyth val = 0; 1649*37da2899SCharles.Forsyth } 1650*37da2899SCharles.Forsyth else { 1651*37da2899SCharles.Forsyth val = distance - compensation; 1652*37da2899SCharles.Forsyth if ( val > 0 ) 1653*37da2899SCharles.Forsyth val = 0; 1654*37da2899SCharles.Forsyth } 1655*37da2899SCharles.Forsyth return val; 1656*37da2899SCharles.Forsyth } 1657*37da2899SCharles.Forsyth 1658*37da2899SCharles.Forsyth 1659*37da2899SCharles.Forsyth /*************************************************************************/ 1660*37da2899SCharles.Forsyth /* */ 1661*37da2899SCharles.Forsyth /* <Function> */ 1662*37da2899SCharles.Forsyth /* Round_To_Grid */ 1663*37da2899SCharles.Forsyth /* */ 1664*37da2899SCharles.Forsyth /* <Description> */ 1665*37da2899SCharles.Forsyth /* Rounds value to grid after adding engine compensation. */ 1666*37da2899SCharles.Forsyth /* */ 1667*37da2899SCharles.Forsyth /* <Input> */ 1668*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1669*37da2899SCharles.Forsyth /* */ 1670*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1671*37da2899SCharles.Forsyth /* */ 1672*37da2899SCharles.Forsyth /* <Return> */ 1673*37da2899SCharles.Forsyth /* Rounded distance. */ 1674*37da2899SCharles.Forsyth /* */ 1675*37da2899SCharles.Forsyth static FT_F26Dot6 Round_To_Grid(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1676*37da2899SCharles.Forsyth Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 1677*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1678*37da2899SCharles.Forsyth { 1679*37da2899SCharles.Forsyth FT_F26Dot6 val; 1680*37da2899SCharles.Forsyth 1681*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1682*37da2899SCharles.Forsyth 1683*37da2899SCharles.Forsyth 1684*37da2899SCharles.Forsyth if ( distance >= 0 ) 1685*37da2899SCharles.Forsyth { 1686*37da2899SCharles.Forsyth val = distance + compensation + 32; 1687*37da2899SCharles.Forsyth if ( val > 0 ) 1688*37da2899SCharles.Forsyth val &= ~63; 1689*37da2899SCharles.Forsyth else 1690*37da2899SCharles.Forsyth val = 0; 1691*37da2899SCharles.Forsyth } 1692*37da2899SCharles.Forsyth else 1693*37da2899SCharles.Forsyth { 1694*37da2899SCharles.Forsyth val = -( ( compensation - distance + 32 ) & -64 ); 1695*37da2899SCharles.Forsyth if ( val > 0 ) 1696*37da2899SCharles.Forsyth val = 0; 1697*37da2899SCharles.Forsyth } 1698*37da2899SCharles.Forsyth 1699*37da2899SCharles.Forsyth return val; 1700*37da2899SCharles.Forsyth } 1701*37da2899SCharles.Forsyth 1702*37da2899SCharles.Forsyth 1703*37da2899SCharles.Forsyth /*************************************************************************/ 1704*37da2899SCharles.Forsyth /* */ 1705*37da2899SCharles.Forsyth /* <Function> */ 1706*37da2899SCharles.Forsyth /* Round_To_Half_Grid */ 1707*37da2899SCharles.Forsyth /* */ 1708*37da2899SCharles.Forsyth /* <Description> */ 1709*37da2899SCharles.Forsyth /* Rounds value to half grid after adding engine compensation. */ 1710*37da2899SCharles.Forsyth /* */ 1711*37da2899SCharles.Forsyth /* <Input> */ 1712*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1713*37da2899SCharles.Forsyth /* */ 1714*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1715*37da2899SCharles.Forsyth /* */ 1716*37da2899SCharles.Forsyth /* <Return> */ 1717*37da2899SCharles.Forsyth /* Rounded distance. */ 1718*37da2899SCharles.Forsyth /* */ 1719*37da2899SCharles.Forsyth static FT_F26Dot6 Round_To_Half_Grid(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1720*37da2899SCharles.Forsyth Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, 1721*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1722*37da2899SCharles.Forsyth { 1723*37da2899SCharles.Forsyth FT_F26Dot6 val; 1724*37da2899SCharles.Forsyth 1725*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1726*37da2899SCharles.Forsyth 1727*37da2899SCharles.Forsyth 1728*37da2899SCharles.Forsyth if ( distance >= 0 ) 1729*37da2899SCharles.Forsyth { 1730*37da2899SCharles.Forsyth val = ( ( distance + compensation ) & -64 ) + 32; 1731*37da2899SCharles.Forsyth if ( val < 0 ) 1732*37da2899SCharles.Forsyth val = 0; 1733*37da2899SCharles.Forsyth } 1734*37da2899SCharles.Forsyth else 1735*37da2899SCharles.Forsyth { 1736*37da2899SCharles.Forsyth val = -( ( (compensation - distance) & -64 ) + 32 ); 1737*37da2899SCharles.Forsyth if ( val > 0 ) 1738*37da2899SCharles.Forsyth val = 0; 1739*37da2899SCharles.Forsyth } 1740*37da2899SCharles.Forsyth 1741*37da2899SCharles.Forsyth return val; 1742*37da2899SCharles.Forsyth } 1743*37da2899SCharles.Forsyth 1744*37da2899SCharles.Forsyth 1745*37da2899SCharles.Forsyth /*************************************************************************/ 1746*37da2899SCharles.Forsyth /* */ 1747*37da2899SCharles.Forsyth /* <Function> */ 1748*37da2899SCharles.Forsyth /* Round_Down_To_Grid */ 1749*37da2899SCharles.Forsyth /* */ 1750*37da2899SCharles.Forsyth /* <Description> */ 1751*37da2899SCharles.Forsyth /* Rounds value down to grid after adding engine compensation. */ 1752*37da2899SCharles.Forsyth /* */ 1753*37da2899SCharles.Forsyth /* <Input> */ 1754*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1755*37da2899SCharles.Forsyth /* */ 1756*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1757*37da2899SCharles.Forsyth /* */ 1758*37da2899SCharles.Forsyth /* <Return> */ 1759*37da2899SCharles.Forsyth /* Rounded distance. */ 1760*37da2899SCharles.Forsyth /* */ 1761*37da2899SCharles.Forsyth static FT_F26Dot6 Round_Down_To_Grid(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1762*37da2899SCharles.Forsyth Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 1763*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1764*37da2899SCharles.Forsyth { 1765*37da2899SCharles.Forsyth FT_F26Dot6 val; 1766*37da2899SCharles.Forsyth 1767*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1768*37da2899SCharles.Forsyth 1769*37da2899SCharles.Forsyth 1770*37da2899SCharles.Forsyth if ( distance >= 0 ) 1771*37da2899SCharles.Forsyth { 1772*37da2899SCharles.Forsyth val = distance + compensation; 1773*37da2899SCharles.Forsyth if ( val > 0 ) 1774*37da2899SCharles.Forsyth val &= ~63; 1775*37da2899SCharles.Forsyth else 1776*37da2899SCharles.Forsyth val = 0; 1777*37da2899SCharles.Forsyth } 1778*37da2899SCharles.Forsyth else 1779*37da2899SCharles.Forsyth { 1780*37da2899SCharles.Forsyth val = -( ( compensation - distance ) & -64 ); 1781*37da2899SCharles.Forsyth if ( val > 0 ) 1782*37da2899SCharles.Forsyth val = 0; 1783*37da2899SCharles.Forsyth } 1784*37da2899SCharles.Forsyth 1785*37da2899SCharles.Forsyth return val; 1786*37da2899SCharles.Forsyth } 1787*37da2899SCharles.Forsyth 1788*37da2899SCharles.Forsyth 1789*37da2899SCharles.Forsyth /*************************************************************************/ 1790*37da2899SCharles.Forsyth /* */ 1791*37da2899SCharles.Forsyth /* <Function> */ 1792*37da2899SCharles.Forsyth /* Round_Up_To_Grid */ 1793*37da2899SCharles.Forsyth /* */ 1794*37da2899SCharles.Forsyth /* <Description> */ 1795*37da2899SCharles.Forsyth /* Rounds value up to grid after adding engine compensation. */ 1796*37da2899SCharles.Forsyth /* */ 1797*37da2899SCharles.Forsyth /* <Input> */ 1798*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1799*37da2899SCharles.Forsyth /* */ 1800*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1801*37da2899SCharles.Forsyth /* */ 1802*37da2899SCharles.Forsyth /* <Return> */ 1803*37da2899SCharles.Forsyth /* Rounded distance. */ 1804*37da2899SCharles.Forsyth /* */ 1805*37da2899SCharles.Forsyth static FT_F26Dot6 Round_Up_To_Grid(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1806*37da2899SCharles.Forsyth Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 1807*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1808*37da2899SCharles.Forsyth { 1809*37da2899SCharles.Forsyth FT_F26Dot6 val; 1810*37da2899SCharles.Forsyth 1811*37da2899SCharles.Forsyth 1812*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1813*37da2899SCharles.Forsyth 1814*37da2899SCharles.Forsyth if ( distance >= 0 ) 1815*37da2899SCharles.Forsyth { 1816*37da2899SCharles.Forsyth val = distance + compensation + 63; 1817*37da2899SCharles.Forsyth if ( val > 0 ) 1818*37da2899SCharles.Forsyth val &= ~63; 1819*37da2899SCharles.Forsyth else 1820*37da2899SCharles.Forsyth val = 0; 1821*37da2899SCharles.Forsyth } 1822*37da2899SCharles.Forsyth else 1823*37da2899SCharles.Forsyth { 1824*37da2899SCharles.Forsyth val = -( ( compensation - distance + 63 ) & -64 ); 1825*37da2899SCharles.Forsyth if ( val > 0 ) 1826*37da2899SCharles.Forsyth val = 0; 1827*37da2899SCharles.Forsyth } 1828*37da2899SCharles.Forsyth 1829*37da2899SCharles.Forsyth return val; 1830*37da2899SCharles.Forsyth } 1831*37da2899SCharles.Forsyth 1832*37da2899SCharles.Forsyth 1833*37da2899SCharles.Forsyth /*************************************************************************/ 1834*37da2899SCharles.Forsyth /* */ 1835*37da2899SCharles.Forsyth /* <Function> */ 1836*37da2899SCharles.Forsyth /* Round_To_Double_Grid */ 1837*37da2899SCharles.Forsyth /* */ 1838*37da2899SCharles.Forsyth /* <Description> */ 1839*37da2899SCharles.Forsyth /* Rounds value to double grid after adding engine compensation. */ 1840*37da2899SCharles.Forsyth /* */ 1841*37da2899SCharles.Forsyth /* <Input> */ 1842*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1843*37da2899SCharles.Forsyth /* */ 1844*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1845*37da2899SCharles.Forsyth /* */ 1846*37da2899SCharles.Forsyth /* <Return> */ 1847*37da2899SCharles.Forsyth /* Rounded distance. */ 1848*37da2899SCharles.Forsyth /* */ 1849*37da2899SCharles.Forsyth static FT_F26Dot6 Round_To_Double_Grid(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1850*37da2899SCharles.Forsyth Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, 1851*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1852*37da2899SCharles.Forsyth { 1853*37da2899SCharles.Forsyth FT_F26Dot6 val; 1854*37da2899SCharles.Forsyth 1855*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 1856*37da2899SCharles.Forsyth 1857*37da2899SCharles.Forsyth 1858*37da2899SCharles.Forsyth if ( distance >= 0 ) 1859*37da2899SCharles.Forsyth { 1860*37da2899SCharles.Forsyth val = distance + compensation + 16; 1861*37da2899SCharles.Forsyth if ( val > 0 ) 1862*37da2899SCharles.Forsyth val &= ~31; 1863*37da2899SCharles.Forsyth else 1864*37da2899SCharles.Forsyth val = 0; 1865*37da2899SCharles.Forsyth } 1866*37da2899SCharles.Forsyth else 1867*37da2899SCharles.Forsyth { 1868*37da2899SCharles.Forsyth val = -( ( compensation - distance + 16 ) & -32 ); 1869*37da2899SCharles.Forsyth if ( val > 0 ) 1870*37da2899SCharles.Forsyth val = 0; 1871*37da2899SCharles.Forsyth } 1872*37da2899SCharles.Forsyth 1873*37da2899SCharles.Forsyth return val; 1874*37da2899SCharles.Forsyth } 1875*37da2899SCharles.Forsyth 1876*37da2899SCharles.Forsyth 1877*37da2899SCharles.Forsyth /*************************************************************************/ 1878*37da2899SCharles.Forsyth /* */ 1879*37da2899SCharles.Forsyth /* <Function> */ 1880*37da2899SCharles.Forsyth /* Round_Super */ 1881*37da2899SCharles.Forsyth /* */ 1882*37da2899SCharles.Forsyth /* <Description> */ 1883*37da2899SCharles.Forsyth /* Super-rounds value to grid after adding engine compensation. */ 1884*37da2899SCharles.Forsyth /* */ 1885*37da2899SCharles.Forsyth /* <Input> */ 1886*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1887*37da2899SCharles.Forsyth /* */ 1888*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1889*37da2899SCharles.Forsyth /* */ 1890*37da2899SCharles.Forsyth /* <Return> */ 1891*37da2899SCharles.Forsyth /* Rounded distance. */ 1892*37da2899SCharles.Forsyth /* */ 1893*37da2899SCharles.Forsyth /* <Note> */ 1894*37da2899SCharles.Forsyth /* The TrueType specification says very few about the relationship */ 1895*37da2899SCharles.Forsyth /* between rounding and engine compensation. However, it seems from */ 1896*37da2899SCharles.Forsyth /* the description of super round that we should add the compensation */ 1897*37da2899SCharles.Forsyth /* before rounding. */ 1898*37da2899SCharles.Forsyth /* */ 1899*37da2899SCharles.Forsyth static FT_F26Dot6 Round_Super(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1900*37da2899SCharles.Forsyth Round_Super( EXEC_OP_ FT_F26Dot6 distance, 1901*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1902*37da2899SCharles.Forsyth { 1903*37da2899SCharles.Forsyth FT_F26Dot6 val; 1904*37da2899SCharles.Forsyth 1905*37da2899SCharles.Forsyth 1906*37da2899SCharles.Forsyth if ( distance >= 0 ) 1907*37da2899SCharles.Forsyth { 1908*37da2899SCharles.Forsyth val = ( distance - CUR.phase + CUR.threshold + compensation ) & 1909*37da2899SCharles.Forsyth -CUR.period; 1910*37da2899SCharles.Forsyth if ( val < 0 ) 1911*37da2899SCharles.Forsyth val = 0; 1912*37da2899SCharles.Forsyth val += CUR.phase; 1913*37da2899SCharles.Forsyth } 1914*37da2899SCharles.Forsyth else 1915*37da2899SCharles.Forsyth { 1916*37da2899SCharles.Forsyth val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & 1917*37da2899SCharles.Forsyth -CUR.period ); 1918*37da2899SCharles.Forsyth if ( val > 0 ) 1919*37da2899SCharles.Forsyth val = 0; 1920*37da2899SCharles.Forsyth val -= CUR.phase; 1921*37da2899SCharles.Forsyth } 1922*37da2899SCharles.Forsyth 1923*37da2899SCharles.Forsyth return val; 1924*37da2899SCharles.Forsyth } 1925*37da2899SCharles.Forsyth 1926*37da2899SCharles.Forsyth 1927*37da2899SCharles.Forsyth /*************************************************************************/ 1928*37da2899SCharles.Forsyth /* */ 1929*37da2899SCharles.Forsyth /* <Function> */ 1930*37da2899SCharles.Forsyth /* Round_Super_45 */ 1931*37da2899SCharles.Forsyth /* */ 1932*37da2899SCharles.Forsyth /* <Description> */ 1933*37da2899SCharles.Forsyth /* Super-rounds value to grid after adding engine compensation. */ 1934*37da2899SCharles.Forsyth /* */ 1935*37da2899SCharles.Forsyth /* <Input> */ 1936*37da2899SCharles.Forsyth /* distance :: The distance to round. */ 1937*37da2899SCharles.Forsyth /* */ 1938*37da2899SCharles.Forsyth /* compensation :: The engine compensation. */ 1939*37da2899SCharles.Forsyth /* */ 1940*37da2899SCharles.Forsyth /* <Return> */ 1941*37da2899SCharles.Forsyth /* Rounded distance. */ 1942*37da2899SCharles.Forsyth /* */ 1943*37da2899SCharles.Forsyth /* <Note> */ 1944*37da2899SCharles.Forsyth /* There is a separate function for Round_Super_45() as we may need */ 1945*37da2899SCharles.Forsyth /* greater precision. */ 1946*37da2899SCharles.Forsyth /* */ 1947*37da2899SCharles.Forsyth static FT_F26Dot6 Round_Super_45(EXEC_OP_ FT_F26Dot6 distance,FT_F26Dot6 compensation)1948*37da2899SCharles.Forsyth Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, 1949*37da2899SCharles.Forsyth FT_F26Dot6 compensation ) 1950*37da2899SCharles.Forsyth { 1951*37da2899SCharles.Forsyth FT_F26Dot6 val; 1952*37da2899SCharles.Forsyth 1953*37da2899SCharles.Forsyth 1954*37da2899SCharles.Forsyth if ( distance >= 0 ) 1955*37da2899SCharles.Forsyth { 1956*37da2899SCharles.Forsyth val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / 1957*37da2899SCharles.Forsyth CUR.period ) * CUR.period; 1958*37da2899SCharles.Forsyth if ( val < 0 ) 1959*37da2899SCharles.Forsyth val = 0; 1960*37da2899SCharles.Forsyth val += CUR.phase; 1961*37da2899SCharles.Forsyth } 1962*37da2899SCharles.Forsyth else 1963*37da2899SCharles.Forsyth { 1964*37da2899SCharles.Forsyth val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / 1965*37da2899SCharles.Forsyth CUR.period ) * CUR.period ); 1966*37da2899SCharles.Forsyth if ( val > 0 ) 1967*37da2899SCharles.Forsyth val = 0; 1968*37da2899SCharles.Forsyth val -= CUR.phase; 1969*37da2899SCharles.Forsyth } 1970*37da2899SCharles.Forsyth 1971*37da2899SCharles.Forsyth return val; 1972*37da2899SCharles.Forsyth } 1973*37da2899SCharles.Forsyth 1974*37da2899SCharles.Forsyth 1975*37da2899SCharles.Forsyth /*************************************************************************/ 1976*37da2899SCharles.Forsyth /* */ 1977*37da2899SCharles.Forsyth /* <Function> */ 1978*37da2899SCharles.Forsyth /* Compute_Round */ 1979*37da2899SCharles.Forsyth /* */ 1980*37da2899SCharles.Forsyth /* <Description> */ 1981*37da2899SCharles.Forsyth /* Sets the rounding mode. */ 1982*37da2899SCharles.Forsyth /* */ 1983*37da2899SCharles.Forsyth /* <Input> */ 1984*37da2899SCharles.Forsyth /* round_mode :: The rounding mode to be used. */ 1985*37da2899SCharles.Forsyth /* */ 1986*37da2899SCharles.Forsyth static void Compute_Round(EXEC_OP_ FT_Byte round_mode)1987*37da2899SCharles.Forsyth Compute_Round( EXEC_OP_ FT_Byte round_mode ) 1988*37da2899SCharles.Forsyth { 1989*37da2899SCharles.Forsyth switch ( round_mode ) 1990*37da2899SCharles.Forsyth { 1991*37da2899SCharles.Forsyth case TT_Round_Off: 1992*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_None; 1993*37da2899SCharles.Forsyth break; 1994*37da2899SCharles.Forsyth 1995*37da2899SCharles.Forsyth case TT_Round_To_Grid: 1996*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Grid; 1997*37da2899SCharles.Forsyth break; 1998*37da2899SCharles.Forsyth 1999*37da2899SCharles.Forsyth case TT_Round_Up_To_Grid: 2000*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; 2001*37da2899SCharles.Forsyth break; 2002*37da2899SCharles.Forsyth 2003*37da2899SCharles.Forsyth case TT_Round_Down_To_Grid: 2004*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; 2005*37da2899SCharles.Forsyth break; 2006*37da2899SCharles.Forsyth 2007*37da2899SCharles.Forsyth case TT_Round_To_Half_Grid: 2008*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; 2009*37da2899SCharles.Forsyth break; 2010*37da2899SCharles.Forsyth 2011*37da2899SCharles.Forsyth case TT_Round_To_Double_Grid: 2012*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; 2013*37da2899SCharles.Forsyth break; 2014*37da2899SCharles.Forsyth 2015*37da2899SCharles.Forsyth case TT_Round_Super: 2016*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Super; 2017*37da2899SCharles.Forsyth break; 2018*37da2899SCharles.Forsyth 2019*37da2899SCharles.Forsyth case TT_Round_Super_45: 2020*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Super_45; 2021*37da2899SCharles.Forsyth break; 2022*37da2899SCharles.Forsyth } 2023*37da2899SCharles.Forsyth } 2024*37da2899SCharles.Forsyth 2025*37da2899SCharles.Forsyth 2026*37da2899SCharles.Forsyth /*************************************************************************/ 2027*37da2899SCharles.Forsyth /* */ 2028*37da2899SCharles.Forsyth /* <Function> */ 2029*37da2899SCharles.Forsyth /* SetSuperRound */ 2030*37da2899SCharles.Forsyth /* */ 2031*37da2899SCharles.Forsyth /* <Description> */ 2032*37da2899SCharles.Forsyth /* Sets Super Round parameters. */ 2033*37da2899SCharles.Forsyth /* */ 2034*37da2899SCharles.Forsyth /* <Input> */ 2035*37da2899SCharles.Forsyth /* GridPeriod :: Grid period */ 2036*37da2899SCharles.Forsyth /* selector :: SROUND opcode */ 2037*37da2899SCharles.Forsyth /* */ 2038*37da2899SCharles.Forsyth static void SetSuperRound(EXEC_OP_ FT_F26Dot6 GridPeriod,FT_Long selector)2039*37da2899SCharles.Forsyth SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, 2040*37da2899SCharles.Forsyth FT_Long selector ) 2041*37da2899SCharles.Forsyth { 2042*37da2899SCharles.Forsyth switch ( (FT_Int)( selector & 0xC0 ) ) 2043*37da2899SCharles.Forsyth { 2044*37da2899SCharles.Forsyth case 0: 2045*37da2899SCharles.Forsyth CUR.period = GridPeriod / 2; 2046*37da2899SCharles.Forsyth break; 2047*37da2899SCharles.Forsyth 2048*37da2899SCharles.Forsyth case 0x40: 2049*37da2899SCharles.Forsyth CUR.period = GridPeriod; 2050*37da2899SCharles.Forsyth break; 2051*37da2899SCharles.Forsyth 2052*37da2899SCharles.Forsyth case 0x80: 2053*37da2899SCharles.Forsyth CUR.period = GridPeriod * 2; 2054*37da2899SCharles.Forsyth break; 2055*37da2899SCharles.Forsyth 2056*37da2899SCharles.Forsyth /* This opcode is reserved, but... */ 2057*37da2899SCharles.Forsyth 2058*37da2899SCharles.Forsyth case 0xC0: 2059*37da2899SCharles.Forsyth CUR.period = GridPeriod; 2060*37da2899SCharles.Forsyth break; 2061*37da2899SCharles.Forsyth } 2062*37da2899SCharles.Forsyth 2063*37da2899SCharles.Forsyth switch ( (FT_Int)( selector & 0x30 ) ) 2064*37da2899SCharles.Forsyth { 2065*37da2899SCharles.Forsyth case 0: 2066*37da2899SCharles.Forsyth CUR.phase = 0; 2067*37da2899SCharles.Forsyth break; 2068*37da2899SCharles.Forsyth 2069*37da2899SCharles.Forsyth case 0x10: 2070*37da2899SCharles.Forsyth CUR.phase = CUR.period / 4; 2071*37da2899SCharles.Forsyth break; 2072*37da2899SCharles.Forsyth 2073*37da2899SCharles.Forsyth case 0x20: 2074*37da2899SCharles.Forsyth CUR.phase = CUR.period / 2; 2075*37da2899SCharles.Forsyth break; 2076*37da2899SCharles.Forsyth 2077*37da2899SCharles.Forsyth case 0x30: 2078*37da2899SCharles.Forsyth CUR.phase = GridPeriod * 3 / 4; 2079*37da2899SCharles.Forsyth break; 2080*37da2899SCharles.Forsyth } 2081*37da2899SCharles.Forsyth 2082*37da2899SCharles.Forsyth if ( (selector & 0x0F) == 0 ) 2083*37da2899SCharles.Forsyth CUR.threshold = CUR.period - 1; 2084*37da2899SCharles.Forsyth else 2085*37da2899SCharles.Forsyth CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; 2086*37da2899SCharles.Forsyth 2087*37da2899SCharles.Forsyth CUR.period /= 256; 2088*37da2899SCharles.Forsyth CUR.phase /= 256; 2089*37da2899SCharles.Forsyth CUR.threshold /= 256; 2090*37da2899SCharles.Forsyth } 2091*37da2899SCharles.Forsyth 2092*37da2899SCharles.Forsyth 2093*37da2899SCharles.Forsyth /*************************************************************************/ 2094*37da2899SCharles.Forsyth /* */ 2095*37da2899SCharles.Forsyth /* <Function> */ 2096*37da2899SCharles.Forsyth /* Project */ 2097*37da2899SCharles.Forsyth /* */ 2098*37da2899SCharles.Forsyth /* <Description> */ 2099*37da2899SCharles.Forsyth /* Computes the projection of vector given by (v2-v1) along the */ 2100*37da2899SCharles.Forsyth /* current projection vector. */ 2101*37da2899SCharles.Forsyth /* */ 2102*37da2899SCharles.Forsyth /* <Input> */ 2103*37da2899SCharles.Forsyth /* v1 :: First input vector. */ 2104*37da2899SCharles.Forsyth /* v2 :: Second input vector. */ 2105*37da2899SCharles.Forsyth /* */ 2106*37da2899SCharles.Forsyth /* <Return> */ 2107*37da2899SCharles.Forsyth /* The distance in F26dot6 format. */ 2108*37da2899SCharles.Forsyth /* */ 2109*37da2899SCharles.Forsyth static FT_F26Dot6 Project(EXEC_OP_ FT_Vector * v1,FT_Vector * v2)2110*37da2899SCharles.Forsyth Project( EXEC_OP_ FT_Vector* v1, 2111*37da2899SCharles.Forsyth FT_Vector* v2 ) 2112*37da2899SCharles.Forsyth { 2113*37da2899SCharles.Forsyth return TT_DotFix14( v1->x - v2->x, 2114*37da2899SCharles.Forsyth v1->y - v2->y, 2115*37da2899SCharles.Forsyth CUR.GS.projVector.x, 2116*37da2899SCharles.Forsyth CUR.GS.projVector.y ); 2117*37da2899SCharles.Forsyth } 2118*37da2899SCharles.Forsyth 2119*37da2899SCharles.Forsyth 2120*37da2899SCharles.Forsyth /*************************************************************************/ 2121*37da2899SCharles.Forsyth /* */ 2122*37da2899SCharles.Forsyth /* <Function> */ 2123*37da2899SCharles.Forsyth /* Dual_Project */ 2124*37da2899SCharles.Forsyth /* */ 2125*37da2899SCharles.Forsyth /* <Description> */ 2126*37da2899SCharles.Forsyth /* Computes the projection of the vector given by (v2-v1) along the */ 2127*37da2899SCharles.Forsyth /* current dual vector. */ 2128*37da2899SCharles.Forsyth /* */ 2129*37da2899SCharles.Forsyth /* <Input> */ 2130*37da2899SCharles.Forsyth /* v1 :: First input vector. */ 2131*37da2899SCharles.Forsyth /* v2 :: Second input vector. */ 2132*37da2899SCharles.Forsyth /* */ 2133*37da2899SCharles.Forsyth /* <Return> */ 2134*37da2899SCharles.Forsyth /* The distance in F26dot6 format. */ 2135*37da2899SCharles.Forsyth /* */ 2136*37da2899SCharles.Forsyth static FT_F26Dot6 Dual_Project(EXEC_OP_ FT_Vector * v1,FT_Vector * v2)2137*37da2899SCharles.Forsyth Dual_Project( EXEC_OP_ FT_Vector* v1, 2138*37da2899SCharles.Forsyth FT_Vector* v2 ) 2139*37da2899SCharles.Forsyth { 2140*37da2899SCharles.Forsyth return TT_DotFix14( v1->x - v2->x, 2141*37da2899SCharles.Forsyth v1->y - v2->y, 2142*37da2899SCharles.Forsyth CUR.GS.dualVector.x, 2143*37da2899SCharles.Forsyth CUR.GS.dualVector.y ); 2144*37da2899SCharles.Forsyth } 2145*37da2899SCharles.Forsyth 2146*37da2899SCharles.Forsyth 2147*37da2899SCharles.Forsyth /*************************************************************************/ 2148*37da2899SCharles.Forsyth /* */ 2149*37da2899SCharles.Forsyth /* <Function> */ 2150*37da2899SCharles.Forsyth /* Free_Project */ 2151*37da2899SCharles.Forsyth /* */ 2152*37da2899SCharles.Forsyth /* <Description> */ 2153*37da2899SCharles.Forsyth /* Computes the projection of the vector given by (v2-v1) along the */ 2154*37da2899SCharles.Forsyth /* current freedom vector. */ 2155*37da2899SCharles.Forsyth /* */ 2156*37da2899SCharles.Forsyth /* <Input> */ 2157*37da2899SCharles.Forsyth /* v1 :: First input vector. */ 2158*37da2899SCharles.Forsyth /* v2 :: Second input vector. */ 2159*37da2899SCharles.Forsyth /* */ 2160*37da2899SCharles.Forsyth /* <Return> */ 2161*37da2899SCharles.Forsyth /* The distance in F26dot6 format. */ 2162*37da2899SCharles.Forsyth /* */ 2163*37da2899SCharles.Forsyth static FT_F26Dot6 Free_Project(EXEC_OP_ FT_Vector * v1,FT_Vector * v2)2164*37da2899SCharles.Forsyth Free_Project( EXEC_OP_ FT_Vector* v1, 2165*37da2899SCharles.Forsyth FT_Vector* v2 ) 2166*37da2899SCharles.Forsyth { 2167*37da2899SCharles.Forsyth return TT_DotFix14( v1->x - v2->x, 2168*37da2899SCharles.Forsyth v1->y - v2->y, 2169*37da2899SCharles.Forsyth CUR.GS.freeVector.x, 2170*37da2899SCharles.Forsyth CUR.GS.freeVector.y ); 2171*37da2899SCharles.Forsyth } 2172*37da2899SCharles.Forsyth 2173*37da2899SCharles.Forsyth 2174*37da2899SCharles.Forsyth /*************************************************************************/ 2175*37da2899SCharles.Forsyth /* */ 2176*37da2899SCharles.Forsyth /* <Function> */ 2177*37da2899SCharles.Forsyth /* Project_x */ 2178*37da2899SCharles.Forsyth /* */ 2179*37da2899SCharles.Forsyth /* <Description> */ 2180*37da2899SCharles.Forsyth /* Computes the projection of the vector given by (v2-v1) along the */ 2181*37da2899SCharles.Forsyth /* horizontal axis. */ 2182*37da2899SCharles.Forsyth /* */ 2183*37da2899SCharles.Forsyth /* <Input> */ 2184*37da2899SCharles.Forsyth /* v1 :: First input vector. */ 2185*37da2899SCharles.Forsyth /* v2 :: Second input vector. */ 2186*37da2899SCharles.Forsyth /* */ 2187*37da2899SCharles.Forsyth /* <Return> */ 2188*37da2899SCharles.Forsyth /* The distance in F26dot6 format. */ 2189*37da2899SCharles.Forsyth /* */ 2190*37da2899SCharles.Forsyth static FT_F26Dot6 Project_x(EXEC_OP_ FT_Vector * v1,FT_Vector * v2)2191*37da2899SCharles.Forsyth Project_x( EXEC_OP_ FT_Vector* v1, 2192*37da2899SCharles.Forsyth FT_Vector* v2 ) 2193*37da2899SCharles.Forsyth { 2194*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 2195*37da2899SCharles.Forsyth 2196*37da2899SCharles.Forsyth return ( v1->x - v2->x ); 2197*37da2899SCharles.Forsyth } 2198*37da2899SCharles.Forsyth 2199*37da2899SCharles.Forsyth 2200*37da2899SCharles.Forsyth /*************************************************************************/ 2201*37da2899SCharles.Forsyth /* */ 2202*37da2899SCharles.Forsyth /* <Function> */ 2203*37da2899SCharles.Forsyth /* Project_y */ 2204*37da2899SCharles.Forsyth /* */ 2205*37da2899SCharles.Forsyth /* <Description> */ 2206*37da2899SCharles.Forsyth /* Computes the projection of the vector given by (v2-v1) along the */ 2207*37da2899SCharles.Forsyth /* vertical axis. */ 2208*37da2899SCharles.Forsyth /* */ 2209*37da2899SCharles.Forsyth /* <Input> */ 2210*37da2899SCharles.Forsyth /* v1 :: First input vector. */ 2211*37da2899SCharles.Forsyth /* v2 :: Second input vector. */ 2212*37da2899SCharles.Forsyth /* */ 2213*37da2899SCharles.Forsyth /* <Return> */ 2214*37da2899SCharles.Forsyth /* The distance in F26dot6 format. */ 2215*37da2899SCharles.Forsyth /* */ 2216*37da2899SCharles.Forsyth static FT_F26Dot6 Project_y(EXEC_OP_ FT_Vector * v1,FT_Vector * v2)2217*37da2899SCharles.Forsyth Project_y( EXEC_OP_ FT_Vector* v1, 2218*37da2899SCharles.Forsyth FT_Vector* v2 ) 2219*37da2899SCharles.Forsyth { 2220*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 2221*37da2899SCharles.Forsyth 2222*37da2899SCharles.Forsyth return ( v1->y - v2->y ); 2223*37da2899SCharles.Forsyth } 2224*37da2899SCharles.Forsyth 2225*37da2899SCharles.Forsyth 2226*37da2899SCharles.Forsyth /*************************************************************************/ 2227*37da2899SCharles.Forsyth /* */ 2228*37da2899SCharles.Forsyth /* <Function> */ 2229*37da2899SCharles.Forsyth /* Compute_Funcs */ 2230*37da2899SCharles.Forsyth /* */ 2231*37da2899SCharles.Forsyth /* <Description> */ 2232*37da2899SCharles.Forsyth /* Computes the projection and movement function pointers according */ 2233*37da2899SCharles.Forsyth /* to the current graphics state. */ 2234*37da2899SCharles.Forsyth /* */ 2235*37da2899SCharles.Forsyth static void Compute_Funcs(EXEC_OP)2236*37da2899SCharles.Forsyth Compute_Funcs( EXEC_OP ) 2237*37da2899SCharles.Forsyth { 2238*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.x == 0x4000 ) 2239*37da2899SCharles.Forsyth { 2240*37da2899SCharles.Forsyth CUR.func_freeProj = (TT_Project_Func)Project_x; 2241*37da2899SCharles.Forsyth CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; 2242*37da2899SCharles.Forsyth } 2243*37da2899SCharles.Forsyth else 2244*37da2899SCharles.Forsyth { 2245*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.y == 0x4000 ) 2246*37da2899SCharles.Forsyth { 2247*37da2899SCharles.Forsyth CUR.func_freeProj = (TT_Project_Func)Project_y; 2248*37da2899SCharles.Forsyth CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; 2249*37da2899SCharles.Forsyth } 2250*37da2899SCharles.Forsyth else 2251*37da2899SCharles.Forsyth { 2252*37da2899SCharles.Forsyth CUR.func_freeProj = (TT_Project_Func)Free_Project; 2253*37da2899SCharles.Forsyth CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + 2254*37da2899SCharles.Forsyth (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; 2255*37da2899SCharles.Forsyth } 2256*37da2899SCharles.Forsyth } 2257*37da2899SCharles.Forsyth 2258*37da2899SCharles.Forsyth if ( CUR.GS.projVector.x == 0x4000 ) 2259*37da2899SCharles.Forsyth CUR.func_project = (TT_Project_Func)Project_x; 2260*37da2899SCharles.Forsyth else 2261*37da2899SCharles.Forsyth { 2262*37da2899SCharles.Forsyth if ( CUR.GS.projVector.y == 0x4000 ) 2263*37da2899SCharles.Forsyth CUR.func_project = (TT_Project_Func)Project_y; 2264*37da2899SCharles.Forsyth else 2265*37da2899SCharles.Forsyth CUR.func_project = (TT_Project_Func)Project; 2266*37da2899SCharles.Forsyth } 2267*37da2899SCharles.Forsyth 2268*37da2899SCharles.Forsyth if ( CUR.GS.dualVector.x == 0x4000 ) 2269*37da2899SCharles.Forsyth CUR.func_dualproj = (TT_Project_Func)Project_x; 2270*37da2899SCharles.Forsyth else 2271*37da2899SCharles.Forsyth { 2272*37da2899SCharles.Forsyth if ( CUR.GS.dualVector.y == 0x4000 ) 2273*37da2899SCharles.Forsyth CUR.func_dualproj = (TT_Project_Func)Project_y; 2274*37da2899SCharles.Forsyth else 2275*37da2899SCharles.Forsyth CUR.func_dualproj = (TT_Project_Func)Dual_Project; 2276*37da2899SCharles.Forsyth } 2277*37da2899SCharles.Forsyth 2278*37da2899SCharles.Forsyth CUR.func_move = (TT_Move_Func)Direct_Move; 2279*37da2899SCharles.Forsyth 2280*37da2899SCharles.Forsyth if ( CUR.F_dot_P == 0x40000000L ) 2281*37da2899SCharles.Forsyth { 2282*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.x == 0x4000 ) 2283*37da2899SCharles.Forsyth CUR.func_move = (TT_Move_Func)Direct_Move_X; 2284*37da2899SCharles.Forsyth else 2285*37da2899SCharles.Forsyth { 2286*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.y == 0x4000 ) 2287*37da2899SCharles.Forsyth CUR.func_move = (TT_Move_Func)Direct_Move_Y; 2288*37da2899SCharles.Forsyth } 2289*37da2899SCharles.Forsyth } 2290*37da2899SCharles.Forsyth 2291*37da2899SCharles.Forsyth /* at small sizes, F_dot_P can become too small, resulting */ 2292*37da2899SCharles.Forsyth /* in overflows and `spikes' in a number of glyphs like `w'. */ 2293*37da2899SCharles.Forsyth 2294*37da2899SCharles.Forsyth if ( ABS( CUR.F_dot_P ) < 0x4000000L ) 2295*37da2899SCharles.Forsyth CUR.F_dot_P = 0x40000000L; 2296*37da2899SCharles.Forsyth 2297*37da2899SCharles.Forsyth /* Disable cached aspect ratio */ 2298*37da2899SCharles.Forsyth CUR.tt_metrics.ratio = 0; 2299*37da2899SCharles.Forsyth } 2300*37da2899SCharles.Forsyth 2301*37da2899SCharles.Forsyth 2302*37da2899SCharles.Forsyth /*************************************************************************/ 2303*37da2899SCharles.Forsyth /* */ 2304*37da2899SCharles.Forsyth /* <Function> */ 2305*37da2899SCharles.Forsyth /* Normalize */ 2306*37da2899SCharles.Forsyth /* */ 2307*37da2899SCharles.Forsyth /* <Description> */ 2308*37da2899SCharles.Forsyth /* Norms a vector. */ 2309*37da2899SCharles.Forsyth /* */ 2310*37da2899SCharles.Forsyth /* <Input> */ 2311*37da2899SCharles.Forsyth /* Vx :: The horizontal input vector coordinate. */ 2312*37da2899SCharles.Forsyth /* Vy :: The vertical input vector coordinate. */ 2313*37da2899SCharles.Forsyth /* */ 2314*37da2899SCharles.Forsyth /* <Output> */ 2315*37da2899SCharles.Forsyth /* R :: The normed unit vector. */ 2316*37da2899SCharles.Forsyth /* */ 2317*37da2899SCharles.Forsyth /* <Return> */ 2318*37da2899SCharles.Forsyth /* Returns FAILURE if a vector parameter is zero. */ 2319*37da2899SCharles.Forsyth /* */ 2320*37da2899SCharles.Forsyth /* <Note> */ 2321*37da2899SCharles.Forsyth /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ 2322*37da2899SCharles.Forsyth /* R is undefined. */ 2323*37da2899SCharles.Forsyth /* */ 2324*37da2899SCharles.Forsyth 2325*37da2899SCharles.Forsyth 2326*37da2899SCharles.Forsyth static FT_Bool Normalize(EXEC_OP_ FT_F26Dot6 Vx,FT_F26Dot6 Vy,FT_UnitVector * R)2327*37da2899SCharles.Forsyth Normalize( EXEC_OP_ FT_F26Dot6 Vx, 2328*37da2899SCharles.Forsyth FT_F26Dot6 Vy, 2329*37da2899SCharles.Forsyth FT_UnitVector* R ) 2330*37da2899SCharles.Forsyth { 2331*37da2899SCharles.Forsyth FT_F26Dot6 W; 2332*37da2899SCharles.Forsyth FT_Bool S1, S2; 2333*37da2899SCharles.Forsyth 2334*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 2335*37da2899SCharles.Forsyth 2336*37da2899SCharles.Forsyth 2337*37da2899SCharles.Forsyth if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) 2338*37da2899SCharles.Forsyth { 2339*37da2899SCharles.Forsyth Vx *= 0x100; 2340*37da2899SCharles.Forsyth Vy *= 0x100; 2341*37da2899SCharles.Forsyth 2342*37da2899SCharles.Forsyth W = TT_VecLen( Vx, Vy ); 2343*37da2899SCharles.Forsyth 2344*37da2899SCharles.Forsyth if ( W == 0 ) 2345*37da2899SCharles.Forsyth { 2346*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! It seems that it is possible to try */ 2347*37da2899SCharles.Forsyth /* to normalize the vector (0,0). Return immediately. */ 2348*37da2899SCharles.Forsyth return SUCCESS; 2349*37da2899SCharles.Forsyth } 2350*37da2899SCharles.Forsyth 2351*37da2899SCharles.Forsyth R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); 2352*37da2899SCharles.Forsyth R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); 2353*37da2899SCharles.Forsyth 2354*37da2899SCharles.Forsyth return SUCCESS; 2355*37da2899SCharles.Forsyth } 2356*37da2899SCharles.Forsyth 2357*37da2899SCharles.Forsyth W = TT_VecLen( Vx, Vy ); 2358*37da2899SCharles.Forsyth 2359*37da2899SCharles.Forsyth Vx = FT_MulDiv( Vx, 0x4000L, W ); 2360*37da2899SCharles.Forsyth Vy = FT_MulDiv( Vy, 0x4000L, W ); 2361*37da2899SCharles.Forsyth 2362*37da2899SCharles.Forsyth W = Vx * Vx + Vy * Vy; 2363*37da2899SCharles.Forsyth 2364*37da2899SCharles.Forsyth /* Now, we want that Sqrt( W ) = 0x4000 */ 2365*37da2899SCharles.Forsyth /* Or 0x1000000 <= W < 0x1004000 */ 2366*37da2899SCharles.Forsyth 2367*37da2899SCharles.Forsyth if ( Vx < 0 ) 2368*37da2899SCharles.Forsyth { 2369*37da2899SCharles.Forsyth Vx = -Vx; 2370*37da2899SCharles.Forsyth S1 = TRUE; 2371*37da2899SCharles.Forsyth } 2372*37da2899SCharles.Forsyth else 2373*37da2899SCharles.Forsyth S1 = FALSE; 2374*37da2899SCharles.Forsyth 2375*37da2899SCharles.Forsyth if ( Vy < 0 ) 2376*37da2899SCharles.Forsyth { 2377*37da2899SCharles.Forsyth Vy = -Vy; 2378*37da2899SCharles.Forsyth S2 = TRUE; 2379*37da2899SCharles.Forsyth } 2380*37da2899SCharles.Forsyth else 2381*37da2899SCharles.Forsyth S2 = FALSE; 2382*37da2899SCharles.Forsyth 2383*37da2899SCharles.Forsyth while ( W < 0x1000000L ) 2384*37da2899SCharles.Forsyth { 2385*37da2899SCharles.Forsyth /* We need to increase W by a minimal amount */ 2386*37da2899SCharles.Forsyth if ( Vx < Vy ) 2387*37da2899SCharles.Forsyth Vx++; 2388*37da2899SCharles.Forsyth else 2389*37da2899SCharles.Forsyth Vy++; 2390*37da2899SCharles.Forsyth 2391*37da2899SCharles.Forsyth W = Vx * Vx + Vy * Vy; 2392*37da2899SCharles.Forsyth } 2393*37da2899SCharles.Forsyth 2394*37da2899SCharles.Forsyth while ( W >= 0x1004000L ) 2395*37da2899SCharles.Forsyth { 2396*37da2899SCharles.Forsyth /* We need to decrease W by a minimal amount */ 2397*37da2899SCharles.Forsyth if ( Vx < Vy ) 2398*37da2899SCharles.Forsyth Vx--; 2399*37da2899SCharles.Forsyth else 2400*37da2899SCharles.Forsyth Vy--; 2401*37da2899SCharles.Forsyth 2402*37da2899SCharles.Forsyth W = Vx * Vx + Vy * Vy; 2403*37da2899SCharles.Forsyth } 2404*37da2899SCharles.Forsyth 2405*37da2899SCharles.Forsyth /* Note that in various cases, we can only */ 2406*37da2899SCharles.Forsyth /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ 2407*37da2899SCharles.Forsyth 2408*37da2899SCharles.Forsyth if ( S1 ) 2409*37da2899SCharles.Forsyth Vx = -Vx; 2410*37da2899SCharles.Forsyth 2411*37da2899SCharles.Forsyth if ( S2 ) 2412*37da2899SCharles.Forsyth Vy = -Vy; 2413*37da2899SCharles.Forsyth 2414*37da2899SCharles.Forsyth R->x = (FT_F2Dot14)Vx; /* Type conversion */ 2415*37da2899SCharles.Forsyth R->y = (FT_F2Dot14)Vy; /* Type conversion */ 2416*37da2899SCharles.Forsyth 2417*37da2899SCharles.Forsyth return SUCCESS; 2418*37da2899SCharles.Forsyth } 2419*37da2899SCharles.Forsyth 2420*37da2899SCharles.Forsyth 2421*37da2899SCharles.Forsyth /*************************************************************************/ 2422*37da2899SCharles.Forsyth /* */ 2423*37da2899SCharles.Forsyth /* Here we start with the implementation of the various opcodes. */ 2424*37da2899SCharles.Forsyth /* */ 2425*37da2899SCharles.Forsyth /*************************************************************************/ 2426*37da2899SCharles.Forsyth 2427*37da2899SCharles.Forsyth 2428*37da2899SCharles.Forsyth static FT_Bool Ins_SxVTL(EXEC_OP_ FT_UShort aIdx1,FT_UShort aIdx2,FT_Int aOpc,FT_UnitVector * Vec)2429*37da2899SCharles.Forsyth Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, 2430*37da2899SCharles.Forsyth FT_UShort aIdx2, 2431*37da2899SCharles.Forsyth FT_Int aOpc, 2432*37da2899SCharles.Forsyth FT_UnitVector* Vec ) 2433*37da2899SCharles.Forsyth { 2434*37da2899SCharles.Forsyth FT_Long A, B, C; 2435*37da2899SCharles.Forsyth FT_Vector* p1; 2436*37da2899SCharles.Forsyth FT_Vector* p2; 2437*37da2899SCharles.Forsyth 2438*37da2899SCharles.Forsyth 2439*37da2899SCharles.Forsyth if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || 2440*37da2899SCharles.Forsyth BOUNDS( aIdx2, CUR.zp1.n_points ) ) 2441*37da2899SCharles.Forsyth { 2442*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 2443*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 2444*37da2899SCharles.Forsyth return FAILURE; 2445*37da2899SCharles.Forsyth } 2446*37da2899SCharles.Forsyth 2447*37da2899SCharles.Forsyth p1 = CUR.zp1.cur + aIdx2; 2448*37da2899SCharles.Forsyth p2 = CUR.zp2.cur + aIdx1; 2449*37da2899SCharles.Forsyth 2450*37da2899SCharles.Forsyth A = p1->x - p2->x; 2451*37da2899SCharles.Forsyth B = p1->y - p2->y; 2452*37da2899SCharles.Forsyth 2453*37da2899SCharles.Forsyth if ( ( aOpc & 1 ) != 0 ) 2454*37da2899SCharles.Forsyth { 2455*37da2899SCharles.Forsyth C = B; /* counter clockwise rotation */ 2456*37da2899SCharles.Forsyth B = A; 2457*37da2899SCharles.Forsyth A = -C; 2458*37da2899SCharles.Forsyth } 2459*37da2899SCharles.Forsyth 2460*37da2899SCharles.Forsyth NORMalize( A, B, Vec ); 2461*37da2899SCharles.Forsyth 2462*37da2899SCharles.Forsyth return SUCCESS; 2463*37da2899SCharles.Forsyth } 2464*37da2899SCharles.Forsyth 2465*37da2899SCharles.Forsyth 2466*37da2899SCharles.Forsyth /* When not using the big switch statements, the interpreter uses a */ 2467*37da2899SCharles.Forsyth /* call table defined later below in this source. Each opcode must */ 2468*37da2899SCharles.Forsyth /* thus have a corresponding function, even trivial ones. */ 2469*37da2899SCharles.Forsyth /* */ 2470*37da2899SCharles.Forsyth /* They are all defined there. */ 2471*37da2899SCharles.Forsyth 2472*37da2899SCharles.Forsyth #define DO_SVTCA \ 2473*37da2899SCharles.Forsyth { \ 2474*37da2899SCharles.Forsyth FT_Short A, B; \ 2475*37da2899SCharles.Forsyth \ 2476*37da2899SCharles.Forsyth \ 2477*37da2899SCharles.Forsyth A = (FT_Short)( CUR.opcode & 1 ) << 14; \ 2478*37da2899SCharles.Forsyth B = A ^ (FT_Short)0x4000; \ 2479*37da2899SCharles.Forsyth \ 2480*37da2899SCharles.Forsyth CUR.GS.freeVector.x = A; \ 2481*37da2899SCharles.Forsyth CUR.GS.projVector.x = A; \ 2482*37da2899SCharles.Forsyth CUR.GS.dualVector.x = A; \ 2483*37da2899SCharles.Forsyth \ 2484*37da2899SCharles.Forsyth CUR.GS.freeVector.y = B; \ 2485*37da2899SCharles.Forsyth CUR.GS.projVector.y = B; \ 2486*37da2899SCharles.Forsyth CUR.GS.dualVector.y = B; \ 2487*37da2899SCharles.Forsyth \ 2488*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2489*37da2899SCharles.Forsyth } 2490*37da2899SCharles.Forsyth 2491*37da2899SCharles.Forsyth 2492*37da2899SCharles.Forsyth #define DO_SPVTCA \ 2493*37da2899SCharles.Forsyth { \ 2494*37da2899SCharles.Forsyth FT_Short A, B; \ 2495*37da2899SCharles.Forsyth \ 2496*37da2899SCharles.Forsyth \ 2497*37da2899SCharles.Forsyth A = (FT_Short)( CUR.opcode & 1 ) << 14; \ 2498*37da2899SCharles.Forsyth B = A ^ (FT_Short)0x4000; \ 2499*37da2899SCharles.Forsyth \ 2500*37da2899SCharles.Forsyth CUR.GS.projVector.x = A; \ 2501*37da2899SCharles.Forsyth CUR.GS.dualVector.x = A; \ 2502*37da2899SCharles.Forsyth \ 2503*37da2899SCharles.Forsyth CUR.GS.projVector.y = B; \ 2504*37da2899SCharles.Forsyth CUR.GS.dualVector.y = B; \ 2505*37da2899SCharles.Forsyth \ 2506*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2507*37da2899SCharles.Forsyth } 2508*37da2899SCharles.Forsyth 2509*37da2899SCharles.Forsyth 2510*37da2899SCharles.Forsyth #define DO_SFVTCA \ 2511*37da2899SCharles.Forsyth { \ 2512*37da2899SCharles.Forsyth FT_Short A, B; \ 2513*37da2899SCharles.Forsyth \ 2514*37da2899SCharles.Forsyth \ 2515*37da2899SCharles.Forsyth A = (FT_Short)( CUR.opcode & 1 ) << 14; \ 2516*37da2899SCharles.Forsyth B = A ^ (FT_Short)0x4000; \ 2517*37da2899SCharles.Forsyth \ 2518*37da2899SCharles.Forsyth CUR.GS.freeVector.x = A; \ 2519*37da2899SCharles.Forsyth CUR.GS.freeVector.y = B; \ 2520*37da2899SCharles.Forsyth \ 2521*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2522*37da2899SCharles.Forsyth } 2523*37da2899SCharles.Forsyth 2524*37da2899SCharles.Forsyth 2525*37da2899SCharles.Forsyth #define DO_SPVTL \ 2526*37da2899SCharles.Forsyth if ( INS_SxVTL( (FT_UShort)args[1], \ 2527*37da2899SCharles.Forsyth (FT_UShort)args[0], \ 2528*37da2899SCharles.Forsyth CUR.opcode, \ 2529*37da2899SCharles.Forsyth &CUR.GS.projVector ) == SUCCESS ) \ 2530*37da2899SCharles.Forsyth { \ 2531*37da2899SCharles.Forsyth CUR.GS.dualVector = CUR.GS.projVector; \ 2532*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2533*37da2899SCharles.Forsyth } 2534*37da2899SCharles.Forsyth 2535*37da2899SCharles.Forsyth 2536*37da2899SCharles.Forsyth #define DO_SFVTL \ 2537*37da2899SCharles.Forsyth if ( INS_SxVTL( (FT_UShort)args[1], \ 2538*37da2899SCharles.Forsyth (FT_UShort)args[0], \ 2539*37da2899SCharles.Forsyth CUR.opcode, \ 2540*37da2899SCharles.Forsyth &CUR.GS.freeVector ) == SUCCESS ) \ 2541*37da2899SCharles.Forsyth COMPUTE_Funcs(); 2542*37da2899SCharles.Forsyth 2543*37da2899SCharles.Forsyth 2544*37da2899SCharles.Forsyth #define DO_SFVTPV \ 2545*37da2899SCharles.Forsyth CUR.GS.freeVector = CUR.GS.projVector; \ 2546*37da2899SCharles.Forsyth COMPUTE_Funcs(); 2547*37da2899SCharles.Forsyth 2548*37da2899SCharles.Forsyth 2549*37da2899SCharles.Forsyth #define DO_SPVFS \ 2550*37da2899SCharles.Forsyth { \ 2551*37da2899SCharles.Forsyth FT_Short S; \ 2552*37da2899SCharles.Forsyth FT_Long X, Y; \ 2553*37da2899SCharles.Forsyth \ 2554*37da2899SCharles.Forsyth \ 2555*37da2899SCharles.Forsyth /* Only use low 16bits, then sign extend */ \ 2556*37da2899SCharles.Forsyth S = (FT_Short)args[1]; \ 2557*37da2899SCharles.Forsyth Y = (FT_Long)S; \ 2558*37da2899SCharles.Forsyth S = (FT_Short)args[0]; \ 2559*37da2899SCharles.Forsyth X = (FT_Long)S; \ 2560*37da2899SCharles.Forsyth \ 2561*37da2899SCharles.Forsyth NORMalize( X, Y, &CUR.GS.projVector ); \ 2562*37da2899SCharles.Forsyth \ 2563*37da2899SCharles.Forsyth CUR.GS.dualVector = CUR.GS.projVector; \ 2564*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2565*37da2899SCharles.Forsyth } 2566*37da2899SCharles.Forsyth 2567*37da2899SCharles.Forsyth 2568*37da2899SCharles.Forsyth #define DO_SFVFS \ 2569*37da2899SCharles.Forsyth { \ 2570*37da2899SCharles.Forsyth FT_Short S; \ 2571*37da2899SCharles.Forsyth FT_Long X, Y; \ 2572*37da2899SCharles.Forsyth \ 2573*37da2899SCharles.Forsyth \ 2574*37da2899SCharles.Forsyth /* Only use low 16bits, then sign extend */ \ 2575*37da2899SCharles.Forsyth S = (FT_Short)args[1]; \ 2576*37da2899SCharles.Forsyth Y = (FT_Long)S; \ 2577*37da2899SCharles.Forsyth S = (FT_Short)args[0]; \ 2578*37da2899SCharles.Forsyth X = S; \ 2579*37da2899SCharles.Forsyth \ 2580*37da2899SCharles.Forsyth NORMalize( X, Y, &CUR.GS.freeVector ); \ 2581*37da2899SCharles.Forsyth COMPUTE_Funcs(); \ 2582*37da2899SCharles.Forsyth } 2583*37da2899SCharles.Forsyth 2584*37da2899SCharles.Forsyth 2585*37da2899SCharles.Forsyth #define DO_GPV \ 2586*37da2899SCharles.Forsyth args[0] = CUR.GS.projVector.x; \ 2587*37da2899SCharles.Forsyth args[1] = CUR.GS.projVector.y; 2588*37da2899SCharles.Forsyth 2589*37da2899SCharles.Forsyth 2590*37da2899SCharles.Forsyth #define DO_GFV \ 2591*37da2899SCharles.Forsyth args[0] = CUR.GS.freeVector.x; \ 2592*37da2899SCharles.Forsyth args[1] = CUR.GS.freeVector.y; 2593*37da2899SCharles.Forsyth 2594*37da2899SCharles.Forsyth 2595*37da2899SCharles.Forsyth #define DO_SRP0 \ 2596*37da2899SCharles.Forsyth CUR.GS.rp0 = (FT_UShort)args[0]; 2597*37da2899SCharles.Forsyth 2598*37da2899SCharles.Forsyth 2599*37da2899SCharles.Forsyth #define DO_SRP1 \ 2600*37da2899SCharles.Forsyth CUR.GS.rp1 = (FT_UShort)args[0]; 2601*37da2899SCharles.Forsyth 2602*37da2899SCharles.Forsyth 2603*37da2899SCharles.Forsyth #define DO_SRP2 \ 2604*37da2899SCharles.Forsyth CUR.GS.rp2 = (FT_UShort)args[0]; 2605*37da2899SCharles.Forsyth 2606*37da2899SCharles.Forsyth 2607*37da2899SCharles.Forsyth #define DO_RTHG \ 2608*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_To_Half_Grid; \ 2609*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; 2610*37da2899SCharles.Forsyth 2611*37da2899SCharles.Forsyth 2612*37da2899SCharles.Forsyth #define DO_RTG \ 2613*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_To_Grid; \ 2614*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Grid; 2615*37da2899SCharles.Forsyth 2616*37da2899SCharles.Forsyth 2617*37da2899SCharles.Forsyth #define DO_RTDG \ 2618*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_To_Double_Grid; \ 2619*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; 2620*37da2899SCharles.Forsyth 2621*37da2899SCharles.Forsyth 2622*37da2899SCharles.Forsyth #define DO_RUTG \ 2623*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_Up_To_Grid; \ 2624*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; 2625*37da2899SCharles.Forsyth 2626*37da2899SCharles.Forsyth 2627*37da2899SCharles.Forsyth #define DO_RDTG \ 2628*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_Down_To_Grid; \ 2629*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; 2630*37da2899SCharles.Forsyth 2631*37da2899SCharles.Forsyth 2632*37da2899SCharles.Forsyth #define DO_ROFF \ 2633*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_Off; \ 2634*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_None; 2635*37da2899SCharles.Forsyth 2636*37da2899SCharles.Forsyth 2637*37da2899SCharles.Forsyth #define DO_SROUND \ 2638*37da2899SCharles.Forsyth SET_SuperRound( 0x4000, args[0] ); \ 2639*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_Super; \ 2640*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Super; 2641*37da2899SCharles.Forsyth 2642*37da2899SCharles.Forsyth 2643*37da2899SCharles.Forsyth #define DO_S45ROUND \ 2644*37da2899SCharles.Forsyth SET_SuperRound( 0x2D41, args[0] ); \ 2645*37da2899SCharles.Forsyth CUR.GS.round_state = TT_Round_Super_45; \ 2646*37da2899SCharles.Forsyth CUR.func_round = (TT_Round_Func)Round_Super_45; 2647*37da2899SCharles.Forsyth 2648*37da2899SCharles.Forsyth 2649*37da2899SCharles.Forsyth #define DO_SLOOP \ 2650*37da2899SCharles.Forsyth if ( args[0] < 0 ) \ 2651*37da2899SCharles.Forsyth CUR.error = TT_Err_Bad_Argument; \ 2652*37da2899SCharles.Forsyth else \ 2653*37da2899SCharles.Forsyth CUR.GS.loop = args[0]; 2654*37da2899SCharles.Forsyth 2655*37da2899SCharles.Forsyth 2656*37da2899SCharles.Forsyth #define DO_SMD \ 2657*37da2899SCharles.Forsyth CUR.GS.minimum_distance = args[0]; 2658*37da2899SCharles.Forsyth 2659*37da2899SCharles.Forsyth 2660*37da2899SCharles.Forsyth #define DO_SCVTCI \ 2661*37da2899SCharles.Forsyth CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; 2662*37da2899SCharles.Forsyth 2663*37da2899SCharles.Forsyth 2664*37da2899SCharles.Forsyth #define DO_SSWCI \ 2665*37da2899SCharles.Forsyth CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; 2666*37da2899SCharles.Forsyth 2667*37da2899SCharles.Forsyth 2668*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! or bug in the Windows engine? */ 2669*37da2899SCharles.Forsyth /* */ 2670*37da2899SCharles.Forsyth /* It seems that the value that is read here is */ 2671*37da2899SCharles.Forsyth /* expressed in 16.16 format rather than in font */ 2672*37da2899SCharles.Forsyth /* units. */ 2673*37da2899SCharles.Forsyth /* */ 2674*37da2899SCharles.Forsyth #define DO_SSW \ 2675*37da2899SCharles.Forsyth CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 ); 2676*37da2899SCharles.Forsyth 2677*37da2899SCharles.Forsyth 2678*37da2899SCharles.Forsyth #define DO_FLIPON \ 2679*37da2899SCharles.Forsyth CUR.GS.auto_flip = TRUE; 2680*37da2899SCharles.Forsyth 2681*37da2899SCharles.Forsyth 2682*37da2899SCharles.Forsyth #define DO_FLIPOFF \ 2683*37da2899SCharles.Forsyth CUR.GS.auto_flip = FALSE; 2684*37da2899SCharles.Forsyth 2685*37da2899SCharles.Forsyth 2686*37da2899SCharles.Forsyth #define DO_SDB \ 2687*37da2899SCharles.Forsyth CUR.GS.delta_base = (FT_Short)args[0]; 2688*37da2899SCharles.Forsyth 2689*37da2899SCharles.Forsyth 2690*37da2899SCharles.Forsyth #define DO_SDS \ 2691*37da2899SCharles.Forsyth CUR.GS.delta_shift = (FT_Short)args[0]; 2692*37da2899SCharles.Forsyth 2693*37da2899SCharles.Forsyth 2694*37da2899SCharles.Forsyth #define DO_MD /* nothing */ 2695*37da2899SCharles.Forsyth 2696*37da2899SCharles.Forsyth 2697*37da2899SCharles.Forsyth #define DO_MPPEM \ 2698*37da2899SCharles.Forsyth args[0] = CURRENT_Ppem(); 2699*37da2899SCharles.Forsyth 2700*37da2899SCharles.Forsyth 2701*37da2899SCharles.Forsyth /* Note: The pointSize should be irrelevant in a given font program; */ 2702*37da2899SCharles.Forsyth /* we thus decide to return only the ppem. */ 2703*37da2899SCharles.Forsyth #if 0 2704*37da2899SCharles.Forsyth 2705*37da2899SCharles.Forsyth #define DO_MPS \ 2706*37da2899SCharles.Forsyth args[0] = CUR.metrics.pointSize; 2707*37da2899SCharles.Forsyth 2708*37da2899SCharles.Forsyth #else 2709*37da2899SCharles.Forsyth 2710*37da2899SCharles.Forsyth #define DO_MPS \ 2711*37da2899SCharles.Forsyth args[0] = CURRENT_Ppem(); 2712*37da2899SCharles.Forsyth 2713*37da2899SCharles.Forsyth #endif /* 0 */ 2714*37da2899SCharles.Forsyth 2715*37da2899SCharles.Forsyth 2716*37da2899SCharles.Forsyth #define DO_DUP \ 2717*37da2899SCharles.Forsyth args[1] = args[0]; 2718*37da2899SCharles.Forsyth 2719*37da2899SCharles.Forsyth 2720*37da2899SCharles.Forsyth #define DO_CLEAR \ 2721*37da2899SCharles.Forsyth CUR.new_top = 0; 2722*37da2899SCharles.Forsyth 2723*37da2899SCharles.Forsyth 2724*37da2899SCharles.Forsyth #define DO_SWAP \ 2725*37da2899SCharles.Forsyth { \ 2726*37da2899SCharles.Forsyth FT_Long L; \ 2727*37da2899SCharles.Forsyth \ 2728*37da2899SCharles.Forsyth \ 2729*37da2899SCharles.Forsyth L = args[0]; \ 2730*37da2899SCharles.Forsyth args[0] = args[1]; \ 2731*37da2899SCharles.Forsyth args[1] = L; \ 2732*37da2899SCharles.Forsyth } 2733*37da2899SCharles.Forsyth 2734*37da2899SCharles.Forsyth 2735*37da2899SCharles.Forsyth #define DO_DEPTH \ 2736*37da2899SCharles.Forsyth args[0] = CUR.top; 2737*37da2899SCharles.Forsyth 2738*37da2899SCharles.Forsyth 2739*37da2899SCharles.Forsyth #define DO_CINDEX \ 2740*37da2899SCharles.Forsyth { \ 2741*37da2899SCharles.Forsyth FT_Long L; \ 2742*37da2899SCharles.Forsyth \ 2743*37da2899SCharles.Forsyth \ 2744*37da2899SCharles.Forsyth L = args[0]; \ 2745*37da2899SCharles.Forsyth \ 2746*37da2899SCharles.Forsyth if ( L <= 0 || L > CUR.args ) \ 2747*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; \ 2748*37da2899SCharles.Forsyth else \ 2749*37da2899SCharles.Forsyth args[0] = CUR.stack[CUR.args - L]; \ 2750*37da2899SCharles.Forsyth } 2751*37da2899SCharles.Forsyth 2752*37da2899SCharles.Forsyth 2753*37da2899SCharles.Forsyth #define DO_JROT \ 2754*37da2899SCharles.Forsyth if ( args[1] != 0 ) \ 2755*37da2899SCharles.Forsyth { \ 2756*37da2899SCharles.Forsyth CUR.IP += args[0]; \ 2757*37da2899SCharles.Forsyth CUR.step_ins = FALSE; \ 2758*37da2899SCharles.Forsyth } 2759*37da2899SCharles.Forsyth 2760*37da2899SCharles.Forsyth 2761*37da2899SCharles.Forsyth #define DO_JMPR \ 2762*37da2899SCharles.Forsyth CUR.IP += args[0]; \ 2763*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 2764*37da2899SCharles.Forsyth 2765*37da2899SCharles.Forsyth 2766*37da2899SCharles.Forsyth #define DO_JROF \ 2767*37da2899SCharles.Forsyth if ( args[1] == 0 ) \ 2768*37da2899SCharles.Forsyth { \ 2769*37da2899SCharles.Forsyth CUR.IP += args[0]; \ 2770*37da2899SCharles.Forsyth CUR.step_ins = FALSE; \ 2771*37da2899SCharles.Forsyth } 2772*37da2899SCharles.Forsyth 2773*37da2899SCharles.Forsyth 2774*37da2899SCharles.Forsyth #define DO_LT \ 2775*37da2899SCharles.Forsyth args[0] = ( args[0] < args[1] ); 2776*37da2899SCharles.Forsyth 2777*37da2899SCharles.Forsyth 2778*37da2899SCharles.Forsyth #define DO_LTEQ \ 2779*37da2899SCharles.Forsyth args[0] = ( args[0] <= args[1] ); 2780*37da2899SCharles.Forsyth 2781*37da2899SCharles.Forsyth 2782*37da2899SCharles.Forsyth #define DO_GT \ 2783*37da2899SCharles.Forsyth args[0] = ( args[0] > args[1] ); 2784*37da2899SCharles.Forsyth 2785*37da2899SCharles.Forsyth 2786*37da2899SCharles.Forsyth #define DO_GTEQ \ 2787*37da2899SCharles.Forsyth args[0] = ( args[0] >= args[1] ); 2788*37da2899SCharles.Forsyth 2789*37da2899SCharles.Forsyth 2790*37da2899SCharles.Forsyth #define DO_EQ \ 2791*37da2899SCharles.Forsyth args[0] = ( args[0] == args[1] ); 2792*37da2899SCharles.Forsyth 2793*37da2899SCharles.Forsyth 2794*37da2899SCharles.Forsyth #define DO_NEQ \ 2795*37da2899SCharles.Forsyth args[0] = ( args[0] != args[1] ); 2796*37da2899SCharles.Forsyth 2797*37da2899SCharles.Forsyth 2798*37da2899SCharles.Forsyth #define DO_ODD \ 2799*37da2899SCharles.Forsyth args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); 2800*37da2899SCharles.Forsyth 2801*37da2899SCharles.Forsyth 2802*37da2899SCharles.Forsyth #define DO_EVEN \ 2803*37da2899SCharles.Forsyth args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); 2804*37da2899SCharles.Forsyth 2805*37da2899SCharles.Forsyth 2806*37da2899SCharles.Forsyth #define DO_AND \ 2807*37da2899SCharles.Forsyth args[0] = ( args[0] && args[1] ); 2808*37da2899SCharles.Forsyth 2809*37da2899SCharles.Forsyth 2810*37da2899SCharles.Forsyth #define DO_OR \ 2811*37da2899SCharles.Forsyth args[0] = ( args[0] || args[1] ); 2812*37da2899SCharles.Forsyth 2813*37da2899SCharles.Forsyth 2814*37da2899SCharles.Forsyth #define DO_NOT \ 2815*37da2899SCharles.Forsyth args[0] = !args[0]; 2816*37da2899SCharles.Forsyth 2817*37da2899SCharles.Forsyth 2818*37da2899SCharles.Forsyth #define DO_ADD \ 2819*37da2899SCharles.Forsyth args[0] += args[1]; 2820*37da2899SCharles.Forsyth 2821*37da2899SCharles.Forsyth 2822*37da2899SCharles.Forsyth #define DO_SUB \ 2823*37da2899SCharles.Forsyth args[0] -= args[1]; 2824*37da2899SCharles.Forsyth 2825*37da2899SCharles.Forsyth 2826*37da2899SCharles.Forsyth #define DO_DIV \ 2827*37da2899SCharles.Forsyth if ( args[1] == 0 ) \ 2828*37da2899SCharles.Forsyth CUR.error = TT_Err_Divide_By_Zero; \ 2829*37da2899SCharles.Forsyth else \ 2830*37da2899SCharles.Forsyth args[0] = TT_MULDIV( args[0], 64L, args[1] ); 2831*37da2899SCharles.Forsyth 2832*37da2899SCharles.Forsyth 2833*37da2899SCharles.Forsyth #define DO_MUL \ 2834*37da2899SCharles.Forsyth args[0] = TT_MULDIV( args[0], args[1], 64L ); 2835*37da2899SCharles.Forsyth 2836*37da2899SCharles.Forsyth 2837*37da2899SCharles.Forsyth #define DO_ABS \ 2838*37da2899SCharles.Forsyth args[0] = ABS( args[0] ); 2839*37da2899SCharles.Forsyth 2840*37da2899SCharles.Forsyth 2841*37da2899SCharles.Forsyth #define DO_NEG \ 2842*37da2899SCharles.Forsyth args[0] = -args[0]; 2843*37da2899SCharles.Forsyth 2844*37da2899SCharles.Forsyth 2845*37da2899SCharles.Forsyth #define DO_FLOOR \ 2846*37da2899SCharles.Forsyth args[0] &= -64; 2847*37da2899SCharles.Forsyth 2848*37da2899SCharles.Forsyth 2849*37da2899SCharles.Forsyth #define DO_CEILING \ 2850*37da2899SCharles.Forsyth args[0] = ( args[0] + 63 ) & -64; 2851*37da2899SCharles.Forsyth 2852*37da2899SCharles.Forsyth 2853*37da2899SCharles.Forsyth #define DO_RS \ 2854*37da2899SCharles.Forsyth { \ 2855*37da2899SCharles.Forsyth FT_ULong I = (FT_ULong)args[0]; \ 2856*37da2899SCharles.Forsyth \ 2857*37da2899SCharles.Forsyth \ 2858*37da2899SCharles.Forsyth if ( BOUNDS( I, CUR.storeSize ) ) \ 2859*37da2899SCharles.Forsyth { \ 2860*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) \ 2861*37da2899SCharles.Forsyth { \ 2862*37da2899SCharles.Forsyth ARRAY_BOUND_ERROR; \ 2863*37da2899SCharles.Forsyth } \ 2864*37da2899SCharles.Forsyth else \ 2865*37da2899SCharles.Forsyth args[0] = 0; \ 2866*37da2899SCharles.Forsyth } \ 2867*37da2899SCharles.Forsyth else \ 2868*37da2899SCharles.Forsyth args[0] = CUR.storage[I]; \ 2869*37da2899SCharles.Forsyth } 2870*37da2899SCharles.Forsyth 2871*37da2899SCharles.Forsyth 2872*37da2899SCharles.Forsyth #define DO_WS \ 2873*37da2899SCharles.Forsyth { \ 2874*37da2899SCharles.Forsyth FT_ULong I = (FT_ULong)args[0]; \ 2875*37da2899SCharles.Forsyth \ 2876*37da2899SCharles.Forsyth \ 2877*37da2899SCharles.Forsyth if ( BOUNDS( I, CUR.storeSize ) ) \ 2878*37da2899SCharles.Forsyth { \ 2879*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) \ 2880*37da2899SCharles.Forsyth { \ 2881*37da2899SCharles.Forsyth ARRAY_BOUND_ERROR; \ 2882*37da2899SCharles.Forsyth } \ 2883*37da2899SCharles.Forsyth } \ 2884*37da2899SCharles.Forsyth else \ 2885*37da2899SCharles.Forsyth CUR.storage[I] = args[1]; \ 2886*37da2899SCharles.Forsyth } 2887*37da2899SCharles.Forsyth 2888*37da2899SCharles.Forsyth 2889*37da2899SCharles.Forsyth #define DO_RCVT \ 2890*37da2899SCharles.Forsyth { \ 2891*37da2899SCharles.Forsyth FT_ULong I = (FT_ULong)args[0]; \ 2892*37da2899SCharles.Forsyth \ 2893*37da2899SCharles.Forsyth \ 2894*37da2899SCharles.Forsyth if ( BOUNDS( I, CUR.cvtSize ) ) \ 2895*37da2899SCharles.Forsyth { \ 2896*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) \ 2897*37da2899SCharles.Forsyth { \ 2898*37da2899SCharles.Forsyth ARRAY_BOUND_ERROR; \ 2899*37da2899SCharles.Forsyth } \ 2900*37da2899SCharles.Forsyth else \ 2901*37da2899SCharles.Forsyth args[0] = 0; \ 2902*37da2899SCharles.Forsyth } \ 2903*37da2899SCharles.Forsyth else \ 2904*37da2899SCharles.Forsyth args[0] = CUR_Func_read_cvt( I ); \ 2905*37da2899SCharles.Forsyth } 2906*37da2899SCharles.Forsyth 2907*37da2899SCharles.Forsyth 2908*37da2899SCharles.Forsyth #define DO_WCVTP \ 2909*37da2899SCharles.Forsyth { \ 2910*37da2899SCharles.Forsyth FT_ULong I = (FT_ULong)args[0]; \ 2911*37da2899SCharles.Forsyth \ 2912*37da2899SCharles.Forsyth \ 2913*37da2899SCharles.Forsyth if ( BOUNDS( I, CUR.cvtSize ) ) \ 2914*37da2899SCharles.Forsyth { \ 2915*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) \ 2916*37da2899SCharles.Forsyth { \ 2917*37da2899SCharles.Forsyth ARRAY_BOUND_ERROR; \ 2918*37da2899SCharles.Forsyth } \ 2919*37da2899SCharles.Forsyth } \ 2920*37da2899SCharles.Forsyth else \ 2921*37da2899SCharles.Forsyth CUR_Func_write_cvt( I, args[1] ); \ 2922*37da2899SCharles.Forsyth } 2923*37da2899SCharles.Forsyth 2924*37da2899SCharles.Forsyth 2925*37da2899SCharles.Forsyth #define DO_WCVTF \ 2926*37da2899SCharles.Forsyth { \ 2927*37da2899SCharles.Forsyth FT_ULong I = (FT_ULong)args[0]; \ 2928*37da2899SCharles.Forsyth \ 2929*37da2899SCharles.Forsyth \ 2930*37da2899SCharles.Forsyth if ( BOUNDS( I, CUR.cvtSize ) ) \ 2931*37da2899SCharles.Forsyth { \ 2932*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) \ 2933*37da2899SCharles.Forsyth { \ 2934*37da2899SCharles.Forsyth ARRAY_BOUND_ERROR; \ 2935*37da2899SCharles.Forsyth } \ 2936*37da2899SCharles.Forsyth } \ 2937*37da2899SCharles.Forsyth else \ 2938*37da2899SCharles.Forsyth CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ 2939*37da2899SCharles.Forsyth } 2940*37da2899SCharles.Forsyth 2941*37da2899SCharles.Forsyth 2942*37da2899SCharles.Forsyth #define DO_DEBUG \ 2943*37da2899SCharles.Forsyth CUR.error = TT_Err_Debug_OpCode; 2944*37da2899SCharles.Forsyth 2945*37da2899SCharles.Forsyth 2946*37da2899SCharles.Forsyth #define DO_ROUND \ 2947*37da2899SCharles.Forsyth args[0] = CUR_Func_round( \ 2948*37da2899SCharles.Forsyth args[0], \ 2949*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); 2950*37da2899SCharles.Forsyth 2951*37da2899SCharles.Forsyth 2952*37da2899SCharles.Forsyth #define DO_NROUND \ 2953*37da2899SCharles.Forsyth args[0] = ROUND_None( args[0], \ 2954*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); 2955*37da2899SCharles.Forsyth 2956*37da2899SCharles.Forsyth 2957*37da2899SCharles.Forsyth #define DO_MAX \ 2958*37da2899SCharles.Forsyth if ( args[1] > args[0] ) \ 2959*37da2899SCharles.Forsyth args[0] = args[1]; 2960*37da2899SCharles.Forsyth 2961*37da2899SCharles.Forsyth 2962*37da2899SCharles.Forsyth #define DO_MIN \ 2963*37da2899SCharles.Forsyth if ( args[1] < args[0] ) \ 2964*37da2899SCharles.Forsyth args[0] = args[1]; 2965*37da2899SCharles.Forsyth 2966*37da2899SCharles.Forsyth 2967*37da2899SCharles.Forsyth #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH 2968*37da2899SCharles.Forsyth 2969*37da2899SCharles.Forsyth 2970*37da2899SCharles.Forsyth #undef ARRAY_BOUND_ERROR 2971*37da2899SCharles.Forsyth #define ARRAY_BOUND_ERROR \ 2972*37da2899SCharles.Forsyth { \ 2973*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; \ 2974*37da2899SCharles.Forsyth return; \ 2975*37da2899SCharles.Forsyth } 2976*37da2899SCharles.Forsyth 2977*37da2899SCharles.Forsyth 2978*37da2899SCharles.Forsyth /*************************************************************************/ 2979*37da2899SCharles.Forsyth /* */ 2980*37da2899SCharles.Forsyth /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ 2981*37da2899SCharles.Forsyth /* Opcode range: 0x00-0x01 */ 2982*37da2899SCharles.Forsyth /* Stack: --> */ 2983*37da2899SCharles.Forsyth /* */ 2984*37da2899SCharles.Forsyth static void Ins_SVTCA(INS_ARG)2985*37da2899SCharles.Forsyth Ins_SVTCA( INS_ARG ) 2986*37da2899SCharles.Forsyth { 2987*37da2899SCharles.Forsyth DO_SVTCA 2988*37da2899SCharles.Forsyth } 2989*37da2899SCharles.Forsyth 2990*37da2899SCharles.Forsyth 2991*37da2899SCharles.Forsyth /*************************************************************************/ 2992*37da2899SCharles.Forsyth /* */ 2993*37da2899SCharles.Forsyth /* SPVTCA[a]: Set PVector to Coordinate Axis */ 2994*37da2899SCharles.Forsyth /* Opcode range: 0x02-0x03 */ 2995*37da2899SCharles.Forsyth /* Stack: --> */ 2996*37da2899SCharles.Forsyth /* */ 2997*37da2899SCharles.Forsyth static void Ins_SPVTCA(INS_ARG)2998*37da2899SCharles.Forsyth Ins_SPVTCA( INS_ARG ) 2999*37da2899SCharles.Forsyth { 3000*37da2899SCharles.Forsyth DO_SPVTCA 3001*37da2899SCharles.Forsyth } 3002*37da2899SCharles.Forsyth 3003*37da2899SCharles.Forsyth 3004*37da2899SCharles.Forsyth /*************************************************************************/ 3005*37da2899SCharles.Forsyth /* */ 3006*37da2899SCharles.Forsyth /* SFVTCA[a]: Set FVector to Coordinate Axis */ 3007*37da2899SCharles.Forsyth /* Opcode range: 0x04-0x05 */ 3008*37da2899SCharles.Forsyth /* Stack: --> */ 3009*37da2899SCharles.Forsyth /* */ 3010*37da2899SCharles.Forsyth static void Ins_SFVTCA(INS_ARG)3011*37da2899SCharles.Forsyth Ins_SFVTCA( INS_ARG ) 3012*37da2899SCharles.Forsyth { 3013*37da2899SCharles.Forsyth DO_SFVTCA 3014*37da2899SCharles.Forsyth } 3015*37da2899SCharles.Forsyth 3016*37da2899SCharles.Forsyth 3017*37da2899SCharles.Forsyth /*************************************************************************/ 3018*37da2899SCharles.Forsyth /* */ 3019*37da2899SCharles.Forsyth /* SPVTL[a]: Set PVector To Line */ 3020*37da2899SCharles.Forsyth /* Opcode range: 0x06-0x07 */ 3021*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 3022*37da2899SCharles.Forsyth /* */ 3023*37da2899SCharles.Forsyth static void Ins_SPVTL(INS_ARG)3024*37da2899SCharles.Forsyth Ins_SPVTL( INS_ARG ) 3025*37da2899SCharles.Forsyth { 3026*37da2899SCharles.Forsyth DO_SPVTL 3027*37da2899SCharles.Forsyth } 3028*37da2899SCharles.Forsyth 3029*37da2899SCharles.Forsyth 3030*37da2899SCharles.Forsyth /*************************************************************************/ 3031*37da2899SCharles.Forsyth /* */ 3032*37da2899SCharles.Forsyth /* SFVTL[a]: Set FVector To Line */ 3033*37da2899SCharles.Forsyth /* Opcode range: 0x08-0x09 */ 3034*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 3035*37da2899SCharles.Forsyth /* */ 3036*37da2899SCharles.Forsyth static void Ins_SFVTL(INS_ARG)3037*37da2899SCharles.Forsyth Ins_SFVTL( INS_ARG ) 3038*37da2899SCharles.Forsyth { 3039*37da2899SCharles.Forsyth DO_SFVTL 3040*37da2899SCharles.Forsyth } 3041*37da2899SCharles.Forsyth 3042*37da2899SCharles.Forsyth 3043*37da2899SCharles.Forsyth /*************************************************************************/ 3044*37da2899SCharles.Forsyth /* */ 3045*37da2899SCharles.Forsyth /* SFVTPV[]: Set FVector To PVector */ 3046*37da2899SCharles.Forsyth /* Opcode range: 0x0E */ 3047*37da2899SCharles.Forsyth /* Stack: --> */ 3048*37da2899SCharles.Forsyth /* */ 3049*37da2899SCharles.Forsyth static void Ins_SFVTPV(INS_ARG)3050*37da2899SCharles.Forsyth Ins_SFVTPV( INS_ARG ) 3051*37da2899SCharles.Forsyth { 3052*37da2899SCharles.Forsyth DO_SFVTPV 3053*37da2899SCharles.Forsyth } 3054*37da2899SCharles.Forsyth 3055*37da2899SCharles.Forsyth 3056*37da2899SCharles.Forsyth /*************************************************************************/ 3057*37da2899SCharles.Forsyth /* */ 3058*37da2899SCharles.Forsyth /* SPVFS[]: Set PVector From Stack */ 3059*37da2899SCharles.Forsyth /* Opcode range: 0x0A */ 3060*37da2899SCharles.Forsyth /* Stack: f2.14 f2.14 --> */ 3061*37da2899SCharles.Forsyth /* */ 3062*37da2899SCharles.Forsyth static void Ins_SPVFS(INS_ARG)3063*37da2899SCharles.Forsyth Ins_SPVFS( INS_ARG ) 3064*37da2899SCharles.Forsyth { 3065*37da2899SCharles.Forsyth DO_SPVFS 3066*37da2899SCharles.Forsyth } 3067*37da2899SCharles.Forsyth 3068*37da2899SCharles.Forsyth 3069*37da2899SCharles.Forsyth /*************************************************************************/ 3070*37da2899SCharles.Forsyth /* */ 3071*37da2899SCharles.Forsyth /* SFVFS[]: Set FVector From Stack */ 3072*37da2899SCharles.Forsyth /* Opcode range: 0x0B */ 3073*37da2899SCharles.Forsyth /* Stack: f2.14 f2.14 --> */ 3074*37da2899SCharles.Forsyth /* */ 3075*37da2899SCharles.Forsyth static void Ins_SFVFS(INS_ARG)3076*37da2899SCharles.Forsyth Ins_SFVFS( INS_ARG ) 3077*37da2899SCharles.Forsyth { 3078*37da2899SCharles.Forsyth DO_SFVFS 3079*37da2899SCharles.Forsyth } 3080*37da2899SCharles.Forsyth 3081*37da2899SCharles.Forsyth 3082*37da2899SCharles.Forsyth /*************************************************************************/ 3083*37da2899SCharles.Forsyth /* */ 3084*37da2899SCharles.Forsyth /* GPV[]: Get Projection Vector */ 3085*37da2899SCharles.Forsyth /* Opcode range: 0x0C */ 3086*37da2899SCharles.Forsyth /* Stack: ef2.14 --> ef2.14 */ 3087*37da2899SCharles.Forsyth /* */ 3088*37da2899SCharles.Forsyth static void Ins_GPV(INS_ARG)3089*37da2899SCharles.Forsyth Ins_GPV( INS_ARG ) 3090*37da2899SCharles.Forsyth { 3091*37da2899SCharles.Forsyth DO_GPV 3092*37da2899SCharles.Forsyth } 3093*37da2899SCharles.Forsyth 3094*37da2899SCharles.Forsyth 3095*37da2899SCharles.Forsyth /*************************************************************************/ 3096*37da2899SCharles.Forsyth /* GFV[]: Get Freedom Vector */ 3097*37da2899SCharles.Forsyth /* Opcode range: 0x0D */ 3098*37da2899SCharles.Forsyth /* Stack: ef2.14 --> ef2.14 */ 3099*37da2899SCharles.Forsyth /* */ 3100*37da2899SCharles.Forsyth static void Ins_GFV(INS_ARG)3101*37da2899SCharles.Forsyth Ins_GFV( INS_ARG ) 3102*37da2899SCharles.Forsyth { 3103*37da2899SCharles.Forsyth DO_GFV 3104*37da2899SCharles.Forsyth } 3105*37da2899SCharles.Forsyth 3106*37da2899SCharles.Forsyth 3107*37da2899SCharles.Forsyth /*************************************************************************/ 3108*37da2899SCharles.Forsyth /* */ 3109*37da2899SCharles.Forsyth /* SRP0[]: Set Reference Point 0 */ 3110*37da2899SCharles.Forsyth /* Opcode range: 0x10 */ 3111*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3112*37da2899SCharles.Forsyth /* */ 3113*37da2899SCharles.Forsyth static void Ins_SRP0(INS_ARG)3114*37da2899SCharles.Forsyth Ins_SRP0( INS_ARG ) 3115*37da2899SCharles.Forsyth { 3116*37da2899SCharles.Forsyth DO_SRP0 3117*37da2899SCharles.Forsyth } 3118*37da2899SCharles.Forsyth 3119*37da2899SCharles.Forsyth 3120*37da2899SCharles.Forsyth /*************************************************************************/ 3121*37da2899SCharles.Forsyth /* */ 3122*37da2899SCharles.Forsyth /* SRP1[]: Set Reference Point 1 */ 3123*37da2899SCharles.Forsyth /* Opcode range: 0x11 */ 3124*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3125*37da2899SCharles.Forsyth /* */ 3126*37da2899SCharles.Forsyth static void Ins_SRP1(INS_ARG)3127*37da2899SCharles.Forsyth Ins_SRP1( INS_ARG ) 3128*37da2899SCharles.Forsyth { 3129*37da2899SCharles.Forsyth DO_SRP1 3130*37da2899SCharles.Forsyth } 3131*37da2899SCharles.Forsyth 3132*37da2899SCharles.Forsyth 3133*37da2899SCharles.Forsyth /*************************************************************************/ 3134*37da2899SCharles.Forsyth /* */ 3135*37da2899SCharles.Forsyth /* SRP2[]: Set Reference Point 2 */ 3136*37da2899SCharles.Forsyth /* Opcode range: 0x12 */ 3137*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3138*37da2899SCharles.Forsyth /* */ 3139*37da2899SCharles.Forsyth static void Ins_SRP2(INS_ARG)3140*37da2899SCharles.Forsyth Ins_SRP2( INS_ARG ) 3141*37da2899SCharles.Forsyth { 3142*37da2899SCharles.Forsyth DO_SRP2 3143*37da2899SCharles.Forsyth } 3144*37da2899SCharles.Forsyth 3145*37da2899SCharles.Forsyth 3146*37da2899SCharles.Forsyth /*************************************************************************/ 3147*37da2899SCharles.Forsyth /* */ 3148*37da2899SCharles.Forsyth /* RTHG[]: Round To Half Grid */ 3149*37da2899SCharles.Forsyth /* Opcode range: 0x19 */ 3150*37da2899SCharles.Forsyth /* Stack: --> */ 3151*37da2899SCharles.Forsyth /* */ 3152*37da2899SCharles.Forsyth static void Ins_RTHG(INS_ARG)3153*37da2899SCharles.Forsyth Ins_RTHG( INS_ARG ) 3154*37da2899SCharles.Forsyth { 3155*37da2899SCharles.Forsyth DO_RTHG 3156*37da2899SCharles.Forsyth } 3157*37da2899SCharles.Forsyth 3158*37da2899SCharles.Forsyth 3159*37da2899SCharles.Forsyth /*************************************************************************/ 3160*37da2899SCharles.Forsyth /* */ 3161*37da2899SCharles.Forsyth /* RTG[]: Round To Grid */ 3162*37da2899SCharles.Forsyth /* Opcode range: 0x18 */ 3163*37da2899SCharles.Forsyth /* Stack: --> */ 3164*37da2899SCharles.Forsyth /* */ 3165*37da2899SCharles.Forsyth static void Ins_RTG(INS_ARG)3166*37da2899SCharles.Forsyth Ins_RTG( INS_ARG ) 3167*37da2899SCharles.Forsyth { 3168*37da2899SCharles.Forsyth DO_RTG 3169*37da2899SCharles.Forsyth } 3170*37da2899SCharles.Forsyth 3171*37da2899SCharles.Forsyth 3172*37da2899SCharles.Forsyth /*************************************************************************/ 3173*37da2899SCharles.Forsyth /* RTDG[]: Round To Double Grid */ 3174*37da2899SCharles.Forsyth /* Opcode range: 0x3D */ 3175*37da2899SCharles.Forsyth /* Stack: --> */ 3176*37da2899SCharles.Forsyth /* */ 3177*37da2899SCharles.Forsyth static void Ins_RTDG(INS_ARG)3178*37da2899SCharles.Forsyth Ins_RTDG( INS_ARG ) 3179*37da2899SCharles.Forsyth { 3180*37da2899SCharles.Forsyth DO_RTDG 3181*37da2899SCharles.Forsyth } 3182*37da2899SCharles.Forsyth 3183*37da2899SCharles.Forsyth 3184*37da2899SCharles.Forsyth /*************************************************************************/ 3185*37da2899SCharles.Forsyth /* RUTG[]: Round Up To Grid */ 3186*37da2899SCharles.Forsyth /* Opcode range: 0x7C */ 3187*37da2899SCharles.Forsyth /* Stack: --> */ 3188*37da2899SCharles.Forsyth /* */ 3189*37da2899SCharles.Forsyth static void Ins_RUTG(INS_ARG)3190*37da2899SCharles.Forsyth Ins_RUTG( INS_ARG ) 3191*37da2899SCharles.Forsyth { 3192*37da2899SCharles.Forsyth DO_RUTG 3193*37da2899SCharles.Forsyth } 3194*37da2899SCharles.Forsyth 3195*37da2899SCharles.Forsyth 3196*37da2899SCharles.Forsyth /*************************************************************************/ 3197*37da2899SCharles.Forsyth /* */ 3198*37da2899SCharles.Forsyth /* RDTG[]: Round Down To Grid */ 3199*37da2899SCharles.Forsyth /* Opcode range: 0x7D */ 3200*37da2899SCharles.Forsyth /* Stack: --> */ 3201*37da2899SCharles.Forsyth /* */ 3202*37da2899SCharles.Forsyth static void Ins_RDTG(INS_ARG)3203*37da2899SCharles.Forsyth Ins_RDTG( INS_ARG ) 3204*37da2899SCharles.Forsyth { 3205*37da2899SCharles.Forsyth DO_RDTG 3206*37da2899SCharles.Forsyth } 3207*37da2899SCharles.Forsyth 3208*37da2899SCharles.Forsyth 3209*37da2899SCharles.Forsyth /*************************************************************************/ 3210*37da2899SCharles.Forsyth /* */ 3211*37da2899SCharles.Forsyth /* ROFF[]: Round OFF */ 3212*37da2899SCharles.Forsyth /* Opcode range: 0x7A */ 3213*37da2899SCharles.Forsyth /* Stack: --> */ 3214*37da2899SCharles.Forsyth /* */ 3215*37da2899SCharles.Forsyth static void Ins_ROFF(INS_ARG)3216*37da2899SCharles.Forsyth Ins_ROFF( INS_ARG ) 3217*37da2899SCharles.Forsyth { 3218*37da2899SCharles.Forsyth DO_ROFF 3219*37da2899SCharles.Forsyth } 3220*37da2899SCharles.Forsyth 3221*37da2899SCharles.Forsyth 3222*37da2899SCharles.Forsyth /*************************************************************************/ 3223*37da2899SCharles.Forsyth /* */ 3224*37da2899SCharles.Forsyth /* SROUND[]: Super ROUND */ 3225*37da2899SCharles.Forsyth /* Opcode range: 0x76 */ 3226*37da2899SCharles.Forsyth /* Stack: Eint8 --> */ 3227*37da2899SCharles.Forsyth /* */ 3228*37da2899SCharles.Forsyth static void Ins_SROUND(INS_ARG)3229*37da2899SCharles.Forsyth Ins_SROUND( INS_ARG ) 3230*37da2899SCharles.Forsyth { 3231*37da2899SCharles.Forsyth DO_SROUND 3232*37da2899SCharles.Forsyth } 3233*37da2899SCharles.Forsyth 3234*37da2899SCharles.Forsyth 3235*37da2899SCharles.Forsyth /*************************************************************************/ 3236*37da2899SCharles.Forsyth /* */ 3237*37da2899SCharles.Forsyth /* S45ROUND[]: Super ROUND 45 degrees */ 3238*37da2899SCharles.Forsyth /* Opcode range: 0x77 */ 3239*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3240*37da2899SCharles.Forsyth /* */ 3241*37da2899SCharles.Forsyth static void Ins_S45ROUND(INS_ARG)3242*37da2899SCharles.Forsyth Ins_S45ROUND( INS_ARG ) 3243*37da2899SCharles.Forsyth { 3244*37da2899SCharles.Forsyth DO_S45ROUND 3245*37da2899SCharles.Forsyth } 3246*37da2899SCharles.Forsyth 3247*37da2899SCharles.Forsyth 3248*37da2899SCharles.Forsyth /*************************************************************************/ 3249*37da2899SCharles.Forsyth /* */ 3250*37da2899SCharles.Forsyth /* SLOOP[]: Set LOOP variable */ 3251*37da2899SCharles.Forsyth /* Opcode range: 0x17 */ 3252*37da2899SCharles.Forsyth /* Stack: int32? --> */ 3253*37da2899SCharles.Forsyth /* */ 3254*37da2899SCharles.Forsyth static void Ins_SLOOP(INS_ARG)3255*37da2899SCharles.Forsyth Ins_SLOOP( INS_ARG ) 3256*37da2899SCharles.Forsyth { 3257*37da2899SCharles.Forsyth DO_SLOOP 3258*37da2899SCharles.Forsyth } 3259*37da2899SCharles.Forsyth 3260*37da2899SCharles.Forsyth 3261*37da2899SCharles.Forsyth /*************************************************************************/ 3262*37da2899SCharles.Forsyth /* */ 3263*37da2899SCharles.Forsyth /* SMD[]: Set Minimum Distance */ 3264*37da2899SCharles.Forsyth /* Opcode range: 0x1A */ 3265*37da2899SCharles.Forsyth /* Stack: f26.6 --> */ 3266*37da2899SCharles.Forsyth /* */ 3267*37da2899SCharles.Forsyth static void Ins_SMD(INS_ARG)3268*37da2899SCharles.Forsyth Ins_SMD( INS_ARG ) 3269*37da2899SCharles.Forsyth { 3270*37da2899SCharles.Forsyth DO_SMD 3271*37da2899SCharles.Forsyth } 3272*37da2899SCharles.Forsyth 3273*37da2899SCharles.Forsyth 3274*37da2899SCharles.Forsyth /*************************************************************************/ 3275*37da2899SCharles.Forsyth /* */ 3276*37da2899SCharles.Forsyth /* SCVTCI[]: Set Control Value Table Cut In */ 3277*37da2899SCharles.Forsyth /* Opcode range: 0x1D */ 3278*37da2899SCharles.Forsyth /* Stack: f26.6 --> */ 3279*37da2899SCharles.Forsyth /* */ 3280*37da2899SCharles.Forsyth static void Ins_SCVTCI(INS_ARG)3281*37da2899SCharles.Forsyth Ins_SCVTCI( INS_ARG ) 3282*37da2899SCharles.Forsyth { 3283*37da2899SCharles.Forsyth DO_SCVTCI 3284*37da2899SCharles.Forsyth } 3285*37da2899SCharles.Forsyth 3286*37da2899SCharles.Forsyth 3287*37da2899SCharles.Forsyth /*************************************************************************/ 3288*37da2899SCharles.Forsyth /* */ 3289*37da2899SCharles.Forsyth /* SSWCI[]: Set Single Width Cut In */ 3290*37da2899SCharles.Forsyth /* Opcode range: 0x1E */ 3291*37da2899SCharles.Forsyth /* Stack: f26.6 --> */ 3292*37da2899SCharles.Forsyth /* */ 3293*37da2899SCharles.Forsyth static void Ins_SSWCI(INS_ARG)3294*37da2899SCharles.Forsyth Ins_SSWCI( INS_ARG ) 3295*37da2899SCharles.Forsyth { 3296*37da2899SCharles.Forsyth DO_SSWCI 3297*37da2899SCharles.Forsyth } 3298*37da2899SCharles.Forsyth 3299*37da2899SCharles.Forsyth 3300*37da2899SCharles.Forsyth /*************************************************************************/ 3301*37da2899SCharles.Forsyth /* */ 3302*37da2899SCharles.Forsyth /* SSW[]: Set Single Width */ 3303*37da2899SCharles.Forsyth /* Opcode range: 0x1F */ 3304*37da2899SCharles.Forsyth /* Stack: int32? --> */ 3305*37da2899SCharles.Forsyth /* */ 3306*37da2899SCharles.Forsyth static void Ins_SSW(INS_ARG)3307*37da2899SCharles.Forsyth Ins_SSW( INS_ARG ) 3308*37da2899SCharles.Forsyth { 3309*37da2899SCharles.Forsyth DO_SSW 3310*37da2899SCharles.Forsyth } 3311*37da2899SCharles.Forsyth 3312*37da2899SCharles.Forsyth 3313*37da2899SCharles.Forsyth /*************************************************************************/ 3314*37da2899SCharles.Forsyth /* */ 3315*37da2899SCharles.Forsyth /* FLIPON[]: Set auto-FLIP to ON */ 3316*37da2899SCharles.Forsyth /* Opcode range: 0x4D */ 3317*37da2899SCharles.Forsyth /* Stack: --> */ 3318*37da2899SCharles.Forsyth /* */ 3319*37da2899SCharles.Forsyth static void Ins_FLIPON(INS_ARG)3320*37da2899SCharles.Forsyth Ins_FLIPON( INS_ARG ) 3321*37da2899SCharles.Forsyth { 3322*37da2899SCharles.Forsyth DO_FLIPON 3323*37da2899SCharles.Forsyth } 3324*37da2899SCharles.Forsyth 3325*37da2899SCharles.Forsyth 3326*37da2899SCharles.Forsyth /*************************************************************************/ 3327*37da2899SCharles.Forsyth /* */ 3328*37da2899SCharles.Forsyth /* FLIPOFF[]: Set auto-FLIP to OFF */ 3329*37da2899SCharles.Forsyth /* Opcode range: 0x4E */ 3330*37da2899SCharles.Forsyth /* Stack: --> */ 3331*37da2899SCharles.Forsyth /* */ 3332*37da2899SCharles.Forsyth static void Ins_FLIPOFF(INS_ARG)3333*37da2899SCharles.Forsyth Ins_FLIPOFF( INS_ARG ) 3334*37da2899SCharles.Forsyth { 3335*37da2899SCharles.Forsyth DO_FLIPOFF 3336*37da2899SCharles.Forsyth } 3337*37da2899SCharles.Forsyth 3338*37da2899SCharles.Forsyth 3339*37da2899SCharles.Forsyth /*************************************************************************/ 3340*37da2899SCharles.Forsyth /* */ 3341*37da2899SCharles.Forsyth /* SANGW[]: Set ANGle Weight */ 3342*37da2899SCharles.Forsyth /* Opcode range: 0x7E */ 3343*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3344*37da2899SCharles.Forsyth /* */ 3345*37da2899SCharles.Forsyth static void Ins_SANGW(INS_ARG)3346*37da2899SCharles.Forsyth Ins_SANGW( INS_ARG ) 3347*37da2899SCharles.Forsyth { 3348*37da2899SCharles.Forsyth /* instruction not supported anymore */ 3349*37da2899SCharles.Forsyth } 3350*37da2899SCharles.Forsyth 3351*37da2899SCharles.Forsyth 3352*37da2899SCharles.Forsyth /*************************************************************************/ 3353*37da2899SCharles.Forsyth /* */ 3354*37da2899SCharles.Forsyth /* SDB[]: Set Delta Base */ 3355*37da2899SCharles.Forsyth /* Opcode range: 0x5E */ 3356*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3357*37da2899SCharles.Forsyth /* */ 3358*37da2899SCharles.Forsyth static void Ins_SDB(INS_ARG)3359*37da2899SCharles.Forsyth Ins_SDB( INS_ARG ) 3360*37da2899SCharles.Forsyth { 3361*37da2899SCharles.Forsyth DO_SDB 3362*37da2899SCharles.Forsyth } 3363*37da2899SCharles.Forsyth 3364*37da2899SCharles.Forsyth 3365*37da2899SCharles.Forsyth /*************************************************************************/ 3366*37da2899SCharles.Forsyth /* */ 3367*37da2899SCharles.Forsyth /* SDS[]: Set Delta Shift */ 3368*37da2899SCharles.Forsyth /* Opcode range: 0x5F */ 3369*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3370*37da2899SCharles.Forsyth /* */ 3371*37da2899SCharles.Forsyth static void Ins_SDS(INS_ARG)3372*37da2899SCharles.Forsyth Ins_SDS( INS_ARG ) 3373*37da2899SCharles.Forsyth { 3374*37da2899SCharles.Forsyth DO_SDS 3375*37da2899SCharles.Forsyth } 3376*37da2899SCharles.Forsyth 3377*37da2899SCharles.Forsyth 3378*37da2899SCharles.Forsyth /*************************************************************************/ 3379*37da2899SCharles.Forsyth /* */ 3380*37da2899SCharles.Forsyth /* MPPEM[]: Measure Pixel Per EM */ 3381*37da2899SCharles.Forsyth /* Opcode range: 0x4B */ 3382*37da2899SCharles.Forsyth /* Stack: --> Euint16 */ 3383*37da2899SCharles.Forsyth /* */ 3384*37da2899SCharles.Forsyth static void Ins_MPPEM(INS_ARG)3385*37da2899SCharles.Forsyth Ins_MPPEM( INS_ARG ) 3386*37da2899SCharles.Forsyth { 3387*37da2899SCharles.Forsyth DO_MPPEM 3388*37da2899SCharles.Forsyth } 3389*37da2899SCharles.Forsyth 3390*37da2899SCharles.Forsyth 3391*37da2899SCharles.Forsyth /*************************************************************************/ 3392*37da2899SCharles.Forsyth /* */ 3393*37da2899SCharles.Forsyth /* MPS[]: Measure Point Size */ 3394*37da2899SCharles.Forsyth /* Opcode range: 0x4C */ 3395*37da2899SCharles.Forsyth /* Stack: --> Euint16 */ 3396*37da2899SCharles.Forsyth /* */ 3397*37da2899SCharles.Forsyth static void Ins_MPS(INS_ARG)3398*37da2899SCharles.Forsyth Ins_MPS( INS_ARG ) 3399*37da2899SCharles.Forsyth { 3400*37da2899SCharles.Forsyth DO_MPS 3401*37da2899SCharles.Forsyth } 3402*37da2899SCharles.Forsyth 3403*37da2899SCharles.Forsyth 3404*37da2899SCharles.Forsyth /*************************************************************************/ 3405*37da2899SCharles.Forsyth /* */ 3406*37da2899SCharles.Forsyth /* DUP[]: DUPlicate the top stack's element */ 3407*37da2899SCharles.Forsyth /* Opcode range: 0x20 */ 3408*37da2899SCharles.Forsyth /* Stack: StkElt --> StkElt StkElt */ 3409*37da2899SCharles.Forsyth /* */ 3410*37da2899SCharles.Forsyth static void Ins_DUP(INS_ARG)3411*37da2899SCharles.Forsyth Ins_DUP( INS_ARG ) 3412*37da2899SCharles.Forsyth { 3413*37da2899SCharles.Forsyth DO_DUP 3414*37da2899SCharles.Forsyth } 3415*37da2899SCharles.Forsyth 3416*37da2899SCharles.Forsyth 3417*37da2899SCharles.Forsyth /*************************************************************************/ 3418*37da2899SCharles.Forsyth /* */ 3419*37da2899SCharles.Forsyth /* POP[]: POP the stack's top element */ 3420*37da2899SCharles.Forsyth /* Opcode range: 0x21 */ 3421*37da2899SCharles.Forsyth /* Stack: StkElt --> */ 3422*37da2899SCharles.Forsyth /* */ 3423*37da2899SCharles.Forsyth static void Ins_POP(INS_ARG)3424*37da2899SCharles.Forsyth Ins_POP( INS_ARG ) 3425*37da2899SCharles.Forsyth { 3426*37da2899SCharles.Forsyth /* nothing to do */ 3427*37da2899SCharles.Forsyth } 3428*37da2899SCharles.Forsyth 3429*37da2899SCharles.Forsyth 3430*37da2899SCharles.Forsyth /*************************************************************************/ 3431*37da2899SCharles.Forsyth /* */ 3432*37da2899SCharles.Forsyth /* CLEAR[]: CLEAR the entire stack */ 3433*37da2899SCharles.Forsyth /* Opcode range: 0x22 */ 3434*37da2899SCharles.Forsyth /* Stack: StkElt... --> */ 3435*37da2899SCharles.Forsyth /* */ 3436*37da2899SCharles.Forsyth static void Ins_CLEAR(INS_ARG)3437*37da2899SCharles.Forsyth Ins_CLEAR( INS_ARG ) 3438*37da2899SCharles.Forsyth { 3439*37da2899SCharles.Forsyth DO_CLEAR 3440*37da2899SCharles.Forsyth } 3441*37da2899SCharles.Forsyth 3442*37da2899SCharles.Forsyth 3443*37da2899SCharles.Forsyth /*************************************************************************/ 3444*37da2899SCharles.Forsyth /* */ 3445*37da2899SCharles.Forsyth /* SWAP[]: SWAP the stack's top two elements */ 3446*37da2899SCharles.Forsyth /* Opcode range: 0x23 */ 3447*37da2899SCharles.Forsyth /* Stack: 2 * StkElt --> 2 * StkElt */ 3448*37da2899SCharles.Forsyth /* */ 3449*37da2899SCharles.Forsyth static void Ins_SWAP(INS_ARG)3450*37da2899SCharles.Forsyth Ins_SWAP( INS_ARG ) 3451*37da2899SCharles.Forsyth { 3452*37da2899SCharles.Forsyth DO_SWAP 3453*37da2899SCharles.Forsyth } 3454*37da2899SCharles.Forsyth 3455*37da2899SCharles.Forsyth 3456*37da2899SCharles.Forsyth /*************************************************************************/ 3457*37da2899SCharles.Forsyth /* */ 3458*37da2899SCharles.Forsyth /* DEPTH[]: return the stack DEPTH */ 3459*37da2899SCharles.Forsyth /* Opcode range: 0x24 */ 3460*37da2899SCharles.Forsyth /* Stack: --> uint32 */ 3461*37da2899SCharles.Forsyth /* */ 3462*37da2899SCharles.Forsyth static void Ins_DEPTH(INS_ARG)3463*37da2899SCharles.Forsyth Ins_DEPTH( INS_ARG ) 3464*37da2899SCharles.Forsyth { 3465*37da2899SCharles.Forsyth DO_DEPTH 3466*37da2899SCharles.Forsyth } 3467*37da2899SCharles.Forsyth 3468*37da2899SCharles.Forsyth 3469*37da2899SCharles.Forsyth /*************************************************************************/ 3470*37da2899SCharles.Forsyth /* */ 3471*37da2899SCharles.Forsyth /* CINDEX[]: Copy INDEXed element */ 3472*37da2899SCharles.Forsyth /* Opcode range: 0x25 */ 3473*37da2899SCharles.Forsyth /* Stack: int32 --> StkElt */ 3474*37da2899SCharles.Forsyth /* */ 3475*37da2899SCharles.Forsyth static void Ins_CINDEX(INS_ARG)3476*37da2899SCharles.Forsyth Ins_CINDEX( INS_ARG ) 3477*37da2899SCharles.Forsyth { 3478*37da2899SCharles.Forsyth DO_CINDEX 3479*37da2899SCharles.Forsyth } 3480*37da2899SCharles.Forsyth 3481*37da2899SCharles.Forsyth 3482*37da2899SCharles.Forsyth /*************************************************************************/ 3483*37da2899SCharles.Forsyth /* */ 3484*37da2899SCharles.Forsyth /* EIF[]: End IF */ 3485*37da2899SCharles.Forsyth /* Opcode range: 0x59 */ 3486*37da2899SCharles.Forsyth /* Stack: --> */ 3487*37da2899SCharles.Forsyth /* */ 3488*37da2899SCharles.Forsyth static void Ins_EIF(INS_ARG)3489*37da2899SCharles.Forsyth Ins_EIF( INS_ARG ) 3490*37da2899SCharles.Forsyth { 3491*37da2899SCharles.Forsyth /* nothing to do */ 3492*37da2899SCharles.Forsyth } 3493*37da2899SCharles.Forsyth 3494*37da2899SCharles.Forsyth 3495*37da2899SCharles.Forsyth /*************************************************************************/ 3496*37da2899SCharles.Forsyth /* */ 3497*37da2899SCharles.Forsyth /* JROT[]: Jump Relative On True */ 3498*37da2899SCharles.Forsyth /* Opcode range: 0x78 */ 3499*37da2899SCharles.Forsyth /* Stack: StkElt int32 --> */ 3500*37da2899SCharles.Forsyth /* */ 3501*37da2899SCharles.Forsyth static void Ins_JROT(INS_ARG)3502*37da2899SCharles.Forsyth Ins_JROT( INS_ARG ) 3503*37da2899SCharles.Forsyth { 3504*37da2899SCharles.Forsyth DO_JROT 3505*37da2899SCharles.Forsyth } 3506*37da2899SCharles.Forsyth 3507*37da2899SCharles.Forsyth 3508*37da2899SCharles.Forsyth /*************************************************************************/ 3509*37da2899SCharles.Forsyth /* */ 3510*37da2899SCharles.Forsyth /* JMPR[]: JuMP Relative */ 3511*37da2899SCharles.Forsyth /* Opcode range: 0x1C */ 3512*37da2899SCharles.Forsyth /* Stack: int32 --> */ 3513*37da2899SCharles.Forsyth /* */ 3514*37da2899SCharles.Forsyth static void Ins_JMPR(INS_ARG)3515*37da2899SCharles.Forsyth Ins_JMPR( INS_ARG ) 3516*37da2899SCharles.Forsyth { 3517*37da2899SCharles.Forsyth DO_JMPR 3518*37da2899SCharles.Forsyth } 3519*37da2899SCharles.Forsyth 3520*37da2899SCharles.Forsyth 3521*37da2899SCharles.Forsyth /*************************************************************************/ 3522*37da2899SCharles.Forsyth /* */ 3523*37da2899SCharles.Forsyth /* JROF[]: Jump Relative On False */ 3524*37da2899SCharles.Forsyth /* Opcode range: 0x79 */ 3525*37da2899SCharles.Forsyth /* Stack: StkElt int32 --> */ 3526*37da2899SCharles.Forsyth /* */ 3527*37da2899SCharles.Forsyth static void Ins_JROF(INS_ARG)3528*37da2899SCharles.Forsyth Ins_JROF( INS_ARG ) 3529*37da2899SCharles.Forsyth { 3530*37da2899SCharles.Forsyth DO_JROF 3531*37da2899SCharles.Forsyth } 3532*37da2899SCharles.Forsyth 3533*37da2899SCharles.Forsyth 3534*37da2899SCharles.Forsyth /*************************************************************************/ 3535*37da2899SCharles.Forsyth /* */ 3536*37da2899SCharles.Forsyth /* LT[]: Less Than */ 3537*37da2899SCharles.Forsyth /* Opcode range: 0x50 */ 3538*37da2899SCharles.Forsyth /* Stack: int32? int32? --> bool */ 3539*37da2899SCharles.Forsyth /* */ 3540*37da2899SCharles.Forsyth static void Ins_LT(INS_ARG)3541*37da2899SCharles.Forsyth Ins_LT( INS_ARG ) 3542*37da2899SCharles.Forsyth { 3543*37da2899SCharles.Forsyth DO_LT 3544*37da2899SCharles.Forsyth } 3545*37da2899SCharles.Forsyth 3546*37da2899SCharles.Forsyth 3547*37da2899SCharles.Forsyth /*************************************************************************/ 3548*37da2899SCharles.Forsyth /* */ 3549*37da2899SCharles.Forsyth /* LTEQ[]: Less Than or EQual */ 3550*37da2899SCharles.Forsyth /* Opcode range: 0x51 */ 3551*37da2899SCharles.Forsyth /* Stack: int32? int32? --> bool */ 3552*37da2899SCharles.Forsyth /* */ 3553*37da2899SCharles.Forsyth static void Ins_LTEQ(INS_ARG)3554*37da2899SCharles.Forsyth Ins_LTEQ( INS_ARG ) 3555*37da2899SCharles.Forsyth { 3556*37da2899SCharles.Forsyth DO_LTEQ 3557*37da2899SCharles.Forsyth } 3558*37da2899SCharles.Forsyth 3559*37da2899SCharles.Forsyth 3560*37da2899SCharles.Forsyth /*************************************************************************/ 3561*37da2899SCharles.Forsyth /* */ 3562*37da2899SCharles.Forsyth /* GT[]: Greater Than */ 3563*37da2899SCharles.Forsyth /* Opcode range: 0x52 */ 3564*37da2899SCharles.Forsyth /* Stack: int32? int32? --> bool */ 3565*37da2899SCharles.Forsyth /* */ 3566*37da2899SCharles.Forsyth static void Ins_GT(INS_ARG)3567*37da2899SCharles.Forsyth Ins_GT( INS_ARG ) 3568*37da2899SCharles.Forsyth { 3569*37da2899SCharles.Forsyth DO_GT 3570*37da2899SCharles.Forsyth } 3571*37da2899SCharles.Forsyth 3572*37da2899SCharles.Forsyth 3573*37da2899SCharles.Forsyth /*************************************************************************/ 3574*37da2899SCharles.Forsyth /* */ 3575*37da2899SCharles.Forsyth /* GTEQ[]: Greater Than or EQual */ 3576*37da2899SCharles.Forsyth /* Opcode range: 0x53 */ 3577*37da2899SCharles.Forsyth /* Stack: int32? int32? --> bool */ 3578*37da2899SCharles.Forsyth /* */ 3579*37da2899SCharles.Forsyth static void Ins_GTEQ(INS_ARG)3580*37da2899SCharles.Forsyth Ins_GTEQ( INS_ARG ) 3581*37da2899SCharles.Forsyth { 3582*37da2899SCharles.Forsyth DO_GTEQ 3583*37da2899SCharles.Forsyth } 3584*37da2899SCharles.Forsyth 3585*37da2899SCharles.Forsyth 3586*37da2899SCharles.Forsyth /*************************************************************************/ 3587*37da2899SCharles.Forsyth /* */ 3588*37da2899SCharles.Forsyth /* EQ[]: EQual */ 3589*37da2899SCharles.Forsyth /* Opcode range: 0x54 */ 3590*37da2899SCharles.Forsyth /* Stack: StkElt StkElt --> bool */ 3591*37da2899SCharles.Forsyth /* */ 3592*37da2899SCharles.Forsyth static void Ins_EQ(INS_ARG)3593*37da2899SCharles.Forsyth Ins_EQ( INS_ARG ) 3594*37da2899SCharles.Forsyth { 3595*37da2899SCharles.Forsyth DO_EQ 3596*37da2899SCharles.Forsyth } 3597*37da2899SCharles.Forsyth 3598*37da2899SCharles.Forsyth 3599*37da2899SCharles.Forsyth /*************************************************************************/ 3600*37da2899SCharles.Forsyth /* */ 3601*37da2899SCharles.Forsyth /* NEQ[]: Not EQual */ 3602*37da2899SCharles.Forsyth /* Opcode range: 0x55 */ 3603*37da2899SCharles.Forsyth /* Stack: StkElt StkElt --> bool */ 3604*37da2899SCharles.Forsyth /* */ 3605*37da2899SCharles.Forsyth static void Ins_NEQ(INS_ARG)3606*37da2899SCharles.Forsyth Ins_NEQ( INS_ARG ) 3607*37da2899SCharles.Forsyth { 3608*37da2899SCharles.Forsyth DO_NEQ 3609*37da2899SCharles.Forsyth } 3610*37da2899SCharles.Forsyth 3611*37da2899SCharles.Forsyth 3612*37da2899SCharles.Forsyth /*************************************************************************/ 3613*37da2899SCharles.Forsyth /* */ 3614*37da2899SCharles.Forsyth /* ODD[]: Is ODD */ 3615*37da2899SCharles.Forsyth /* Opcode range: 0x56 */ 3616*37da2899SCharles.Forsyth /* Stack: f26.6 --> bool */ 3617*37da2899SCharles.Forsyth /* */ 3618*37da2899SCharles.Forsyth static void Ins_ODD(INS_ARG)3619*37da2899SCharles.Forsyth Ins_ODD( INS_ARG ) 3620*37da2899SCharles.Forsyth { 3621*37da2899SCharles.Forsyth DO_ODD 3622*37da2899SCharles.Forsyth } 3623*37da2899SCharles.Forsyth 3624*37da2899SCharles.Forsyth 3625*37da2899SCharles.Forsyth /*************************************************************************/ 3626*37da2899SCharles.Forsyth /* */ 3627*37da2899SCharles.Forsyth /* EVEN[]: Is EVEN */ 3628*37da2899SCharles.Forsyth /* Opcode range: 0x57 */ 3629*37da2899SCharles.Forsyth /* Stack: f26.6 --> bool */ 3630*37da2899SCharles.Forsyth /* */ 3631*37da2899SCharles.Forsyth static void Ins_EVEN(INS_ARG)3632*37da2899SCharles.Forsyth Ins_EVEN( INS_ARG ) 3633*37da2899SCharles.Forsyth { 3634*37da2899SCharles.Forsyth DO_EVEN 3635*37da2899SCharles.Forsyth } 3636*37da2899SCharles.Forsyth 3637*37da2899SCharles.Forsyth 3638*37da2899SCharles.Forsyth /*************************************************************************/ 3639*37da2899SCharles.Forsyth /* */ 3640*37da2899SCharles.Forsyth /* AND[]: logical AND */ 3641*37da2899SCharles.Forsyth /* Opcode range: 0x5A */ 3642*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> uint32 */ 3643*37da2899SCharles.Forsyth /* */ 3644*37da2899SCharles.Forsyth static void Ins_AND(INS_ARG)3645*37da2899SCharles.Forsyth Ins_AND( INS_ARG ) 3646*37da2899SCharles.Forsyth { 3647*37da2899SCharles.Forsyth DO_AND 3648*37da2899SCharles.Forsyth } 3649*37da2899SCharles.Forsyth 3650*37da2899SCharles.Forsyth 3651*37da2899SCharles.Forsyth /*************************************************************************/ 3652*37da2899SCharles.Forsyth /* */ 3653*37da2899SCharles.Forsyth /* OR[]: logical OR */ 3654*37da2899SCharles.Forsyth /* Opcode range: 0x5B */ 3655*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> uint32 */ 3656*37da2899SCharles.Forsyth /* */ 3657*37da2899SCharles.Forsyth static void Ins_OR(INS_ARG)3658*37da2899SCharles.Forsyth Ins_OR( INS_ARG ) 3659*37da2899SCharles.Forsyth { 3660*37da2899SCharles.Forsyth DO_OR 3661*37da2899SCharles.Forsyth } 3662*37da2899SCharles.Forsyth 3663*37da2899SCharles.Forsyth 3664*37da2899SCharles.Forsyth /*************************************************************************/ 3665*37da2899SCharles.Forsyth /* */ 3666*37da2899SCharles.Forsyth /* NOT[]: logical NOT */ 3667*37da2899SCharles.Forsyth /* Opcode range: 0x5C */ 3668*37da2899SCharles.Forsyth /* Stack: StkElt --> uint32 */ 3669*37da2899SCharles.Forsyth /* */ 3670*37da2899SCharles.Forsyth static void Ins_NOT(INS_ARG)3671*37da2899SCharles.Forsyth Ins_NOT( INS_ARG ) 3672*37da2899SCharles.Forsyth { 3673*37da2899SCharles.Forsyth DO_NOT 3674*37da2899SCharles.Forsyth } 3675*37da2899SCharles.Forsyth 3676*37da2899SCharles.Forsyth 3677*37da2899SCharles.Forsyth /*************************************************************************/ 3678*37da2899SCharles.Forsyth /* */ 3679*37da2899SCharles.Forsyth /* ADD[]: ADD */ 3680*37da2899SCharles.Forsyth /* Opcode range: 0x60 */ 3681*37da2899SCharles.Forsyth /* Stack: f26.6 f26.6 --> f26.6 */ 3682*37da2899SCharles.Forsyth /* */ 3683*37da2899SCharles.Forsyth static void Ins_ADD(INS_ARG)3684*37da2899SCharles.Forsyth Ins_ADD( INS_ARG ) 3685*37da2899SCharles.Forsyth { 3686*37da2899SCharles.Forsyth DO_ADD 3687*37da2899SCharles.Forsyth } 3688*37da2899SCharles.Forsyth 3689*37da2899SCharles.Forsyth 3690*37da2899SCharles.Forsyth /*************************************************************************/ 3691*37da2899SCharles.Forsyth /* */ 3692*37da2899SCharles.Forsyth /* SUB[]: SUBtract */ 3693*37da2899SCharles.Forsyth /* Opcode range: 0x61 */ 3694*37da2899SCharles.Forsyth /* Stack: f26.6 f26.6 --> f26.6 */ 3695*37da2899SCharles.Forsyth /* */ 3696*37da2899SCharles.Forsyth static void Ins_SUB(INS_ARG)3697*37da2899SCharles.Forsyth Ins_SUB( INS_ARG ) 3698*37da2899SCharles.Forsyth { 3699*37da2899SCharles.Forsyth DO_SUB 3700*37da2899SCharles.Forsyth } 3701*37da2899SCharles.Forsyth 3702*37da2899SCharles.Forsyth 3703*37da2899SCharles.Forsyth /*************************************************************************/ 3704*37da2899SCharles.Forsyth /* */ 3705*37da2899SCharles.Forsyth /* DIV[]: DIVide */ 3706*37da2899SCharles.Forsyth /* Opcode range: 0x62 */ 3707*37da2899SCharles.Forsyth /* Stack: f26.6 f26.6 --> f26.6 */ 3708*37da2899SCharles.Forsyth /* */ 3709*37da2899SCharles.Forsyth static void Ins_DIV(INS_ARG)3710*37da2899SCharles.Forsyth Ins_DIV( INS_ARG ) 3711*37da2899SCharles.Forsyth { 3712*37da2899SCharles.Forsyth DO_DIV 3713*37da2899SCharles.Forsyth } 3714*37da2899SCharles.Forsyth 3715*37da2899SCharles.Forsyth 3716*37da2899SCharles.Forsyth /*************************************************************************/ 3717*37da2899SCharles.Forsyth /* */ 3718*37da2899SCharles.Forsyth /* MUL[]: MULtiply */ 3719*37da2899SCharles.Forsyth /* Opcode range: 0x63 */ 3720*37da2899SCharles.Forsyth /* Stack: f26.6 f26.6 --> f26.6 */ 3721*37da2899SCharles.Forsyth /* */ 3722*37da2899SCharles.Forsyth static void Ins_MUL(INS_ARG)3723*37da2899SCharles.Forsyth Ins_MUL( INS_ARG ) 3724*37da2899SCharles.Forsyth { 3725*37da2899SCharles.Forsyth DO_MUL 3726*37da2899SCharles.Forsyth } 3727*37da2899SCharles.Forsyth 3728*37da2899SCharles.Forsyth 3729*37da2899SCharles.Forsyth /*************************************************************************/ 3730*37da2899SCharles.Forsyth /* */ 3731*37da2899SCharles.Forsyth /* ABS[]: ABSolute value */ 3732*37da2899SCharles.Forsyth /* Opcode range: 0x64 */ 3733*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3734*37da2899SCharles.Forsyth /* */ 3735*37da2899SCharles.Forsyth static void Ins_ABS(INS_ARG)3736*37da2899SCharles.Forsyth Ins_ABS( INS_ARG ) 3737*37da2899SCharles.Forsyth { 3738*37da2899SCharles.Forsyth DO_ABS 3739*37da2899SCharles.Forsyth } 3740*37da2899SCharles.Forsyth 3741*37da2899SCharles.Forsyth 3742*37da2899SCharles.Forsyth /*************************************************************************/ 3743*37da2899SCharles.Forsyth /* */ 3744*37da2899SCharles.Forsyth /* NEG[]: NEGate */ 3745*37da2899SCharles.Forsyth /* Opcode range: 0x65 */ 3746*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3747*37da2899SCharles.Forsyth /* */ 3748*37da2899SCharles.Forsyth static void Ins_NEG(INS_ARG)3749*37da2899SCharles.Forsyth Ins_NEG( INS_ARG ) 3750*37da2899SCharles.Forsyth { 3751*37da2899SCharles.Forsyth DO_NEG 3752*37da2899SCharles.Forsyth } 3753*37da2899SCharles.Forsyth 3754*37da2899SCharles.Forsyth 3755*37da2899SCharles.Forsyth /*************************************************************************/ 3756*37da2899SCharles.Forsyth /* */ 3757*37da2899SCharles.Forsyth /* FLOOR[]: FLOOR */ 3758*37da2899SCharles.Forsyth /* Opcode range: 0x66 */ 3759*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3760*37da2899SCharles.Forsyth /* */ 3761*37da2899SCharles.Forsyth static void Ins_FLOOR(INS_ARG)3762*37da2899SCharles.Forsyth Ins_FLOOR( INS_ARG ) 3763*37da2899SCharles.Forsyth { 3764*37da2899SCharles.Forsyth DO_FLOOR 3765*37da2899SCharles.Forsyth } 3766*37da2899SCharles.Forsyth 3767*37da2899SCharles.Forsyth 3768*37da2899SCharles.Forsyth /*************************************************************************/ 3769*37da2899SCharles.Forsyth /* */ 3770*37da2899SCharles.Forsyth /* CEILING[]: CEILING */ 3771*37da2899SCharles.Forsyth /* Opcode range: 0x67 */ 3772*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3773*37da2899SCharles.Forsyth /* */ 3774*37da2899SCharles.Forsyth static void Ins_CEILING(INS_ARG)3775*37da2899SCharles.Forsyth Ins_CEILING( INS_ARG ) 3776*37da2899SCharles.Forsyth { 3777*37da2899SCharles.Forsyth DO_CEILING 3778*37da2899SCharles.Forsyth } 3779*37da2899SCharles.Forsyth 3780*37da2899SCharles.Forsyth 3781*37da2899SCharles.Forsyth /*************************************************************************/ 3782*37da2899SCharles.Forsyth /* */ 3783*37da2899SCharles.Forsyth /* RS[]: Read Store */ 3784*37da2899SCharles.Forsyth /* Opcode range: 0x43 */ 3785*37da2899SCharles.Forsyth /* Stack: uint32 --> uint32 */ 3786*37da2899SCharles.Forsyth /* */ 3787*37da2899SCharles.Forsyth static void Ins_RS(INS_ARG)3788*37da2899SCharles.Forsyth Ins_RS( INS_ARG ) 3789*37da2899SCharles.Forsyth { 3790*37da2899SCharles.Forsyth DO_RS 3791*37da2899SCharles.Forsyth } 3792*37da2899SCharles.Forsyth 3793*37da2899SCharles.Forsyth 3794*37da2899SCharles.Forsyth /*************************************************************************/ 3795*37da2899SCharles.Forsyth /* */ 3796*37da2899SCharles.Forsyth /* WS[]: Write Store */ 3797*37da2899SCharles.Forsyth /* Opcode range: 0x42 */ 3798*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 3799*37da2899SCharles.Forsyth /* */ 3800*37da2899SCharles.Forsyth static void Ins_WS(INS_ARG)3801*37da2899SCharles.Forsyth Ins_WS( INS_ARG ) 3802*37da2899SCharles.Forsyth { 3803*37da2899SCharles.Forsyth DO_WS 3804*37da2899SCharles.Forsyth } 3805*37da2899SCharles.Forsyth 3806*37da2899SCharles.Forsyth 3807*37da2899SCharles.Forsyth /*************************************************************************/ 3808*37da2899SCharles.Forsyth /* */ 3809*37da2899SCharles.Forsyth /* WCVTP[]: Write CVT in Pixel units */ 3810*37da2899SCharles.Forsyth /* Opcode range: 0x44 */ 3811*37da2899SCharles.Forsyth /* Stack: f26.6 uint32 --> */ 3812*37da2899SCharles.Forsyth /* */ 3813*37da2899SCharles.Forsyth static void Ins_WCVTP(INS_ARG)3814*37da2899SCharles.Forsyth Ins_WCVTP( INS_ARG ) 3815*37da2899SCharles.Forsyth { 3816*37da2899SCharles.Forsyth DO_WCVTP 3817*37da2899SCharles.Forsyth } 3818*37da2899SCharles.Forsyth 3819*37da2899SCharles.Forsyth 3820*37da2899SCharles.Forsyth /*************************************************************************/ 3821*37da2899SCharles.Forsyth /* */ 3822*37da2899SCharles.Forsyth /* WCVTF[]: Write CVT in Funits */ 3823*37da2899SCharles.Forsyth /* Opcode range: 0x70 */ 3824*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 3825*37da2899SCharles.Forsyth /* */ 3826*37da2899SCharles.Forsyth static void Ins_WCVTF(INS_ARG)3827*37da2899SCharles.Forsyth Ins_WCVTF( INS_ARG ) 3828*37da2899SCharles.Forsyth { 3829*37da2899SCharles.Forsyth DO_WCVTF 3830*37da2899SCharles.Forsyth } 3831*37da2899SCharles.Forsyth 3832*37da2899SCharles.Forsyth 3833*37da2899SCharles.Forsyth /*************************************************************************/ 3834*37da2899SCharles.Forsyth /* */ 3835*37da2899SCharles.Forsyth /* RCVT[]: Read CVT */ 3836*37da2899SCharles.Forsyth /* Opcode range: 0x45 */ 3837*37da2899SCharles.Forsyth /* Stack: uint32 --> f26.6 */ 3838*37da2899SCharles.Forsyth /* */ 3839*37da2899SCharles.Forsyth static void Ins_RCVT(INS_ARG)3840*37da2899SCharles.Forsyth Ins_RCVT( INS_ARG ) 3841*37da2899SCharles.Forsyth { 3842*37da2899SCharles.Forsyth DO_RCVT 3843*37da2899SCharles.Forsyth } 3844*37da2899SCharles.Forsyth 3845*37da2899SCharles.Forsyth 3846*37da2899SCharles.Forsyth /*************************************************************************/ 3847*37da2899SCharles.Forsyth /* */ 3848*37da2899SCharles.Forsyth /* AA[]: Adjust Angle */ 3849*37da2899SCharles.Forsyth /* Opcode range: 0x7F */ 3850*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3851*37da2899SCharles.Forsyth /* */ 3852*37da2899SCharles.Forsyth static void Ins_AA(INS_ARG)3853*37da2899SCharles.Forsyth Ins_AA( INS_ARG ) 3854*37da2899SCharles.Forsyth { 3855*37da2899SCharles.Forsyth /* intentionally no longer supported */ 3856*37da2899SCharles.Forsyth } 3857*37da2899SCharles.Forsyth 3858*37da2899SCharles.Forsyth 3859*37da2899SCharles.Forsyth /*************************************************************************/ 3860*37da2899SCharles.Forsyth /* */ 3861*37da2899SCharles.Forsyth /* DEBUG[]: DEBUG. Unsupported. */ 3862*37da2899SCharles.Forsyth /* Opcode range: 0x4F */ 3863*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 3864*37da2899SCharles.Forsyth /* */ 3865*37da2899SCharles.Forsyth /* Note: The original instruction pops a value from the stack. */ 3866*37da2899SCharles.Forsyth /* */ 3867*37da2899SCharles.Forsyth static void Ins_DEBUG(INS_ARG)3868*37da2899SCharles.Forsyth Ins_DEBUG( INS_ARG ) 3869*37da2899SCharles.Forsyth { 3870*37da2899SCharles.Forsyth DO_DEBUG 3871*37da2899SCharles.Forsyth } 3872*37da2899SCharles.Forsyth 3873*37da2899SCharles.Forsyth 3874*37da2899SCharles.Forsyth /*************************************************************************/ 3875*37da2899SCharles.Forsyth /* */ 3876*37da2899SCharles.Forsyth /* ROUND[ab]: ROUND value */ 3877*37da2899SCharles.Forsyth /* Opcode range: 0x68-0x6B */ 3878*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3879*37da2899SCharles.Forsyth /* */ 3880*37da2899SCharles.Forsyth static void Ins_ROUND(INS_ARG)3881*37da2899SCharles.Forsyth Ins_ROUND( INS_ARG ) 3882*37da2899SCharles.Forsyth { 3883*37da2899SCharles.Forsyth DO_ROUND 3884*37da2899SCharles.Forsyth } 3885*37da2899SCharles.Forsyth 3886*37da2899SCharles.Forsyth 3887*37da2899SCharles.Forsyth /*************************************************************************/ 3888*37da2899SCharles.Forsyth /* */ 3889*37da2899SCharles.Forsyth /* NROUND[ab]: No ROUNDing of value */ 3890*37da2899SCharles.Forsyth /* Opcode range: 0x6C-0x6F */ 3891*37da2899SCharles.Forsyth /* Stack: f26.6 --> f26.6 */ 3892*37da2899SCharles.Forsyth /* */ 3893*37da2899SCharles.Forsyth static void Ins_NROUND(INS_ARG)3894*37da2899SCharles.Forsyth Ins_NROUND( INS_ARG ) 3895*37da2899SCharles.Forsyth { 3896*37da2899SCharles.Forsyth DO_NROUND 3897*37da2899SCharles.Forsyth } 3898*37da2899SCharles.Forsyth 3899*37da2899SCharles.Forsyth 3900*37da2899SCharles.Forsyth /*************************************************************************/ 3901*37da2899SCharles.Forsyth /* */ 3902*37da2899SCharles.Forsyth /* MAX[]: MAXimum */ 3903*37da2899SCharles.Forsyth /* Opcode range: 0x68 */ 3904*37da2899SCharles.Forsyth /* Stack: int32? int32? --> int32 */ 3905*37da2899SCharles.Forsyth /* */ 3906*37da2899SCharles.Forsyth static void Ins_MAX(INS_ARG)3907*37da2899SCharles.Forsyth Ins_MAX( INS_ARG ) 3908*37da2899SCharles.Forsyth { 3909*37da2899SCharles.Forsyth DO_MAX 3910*37da2899SCharles.Forsyth } 3911*37da2899SCharles.Forsyth 3912*37da2899SCharles.Forsyth 3913*37da2899SCharles.Forsyth /*************************************************************************/ 3914*37da2899SCharles.Forsyth /* */ 3915*37da2899SCharles.Forsyth /* MIN[]: MINimum */ 3916*37da2899SCharles.Forsyth /* Opcode range: 0x69 */ 3917*37da2899SCharles.Forsyth /* Stack: int32? int32? --> int32 */ 3918*37da2899SCharles.Forsyth /* */ 3919*37da2899SCharles.Forsyth static void Ins_MIN(INS_ARG)3920*37da2899SCharles.Forsyth Ins_MIN( INS_ARG ) 3921*37da2899SCharles.Forsyth { 3922*37da2899SCharles.Forsyth DO_MIN 3923*37da2899SCharles.Forsyth } 3924*37da2899SCharles.Forsyth 3925*37da2899SCharles.Forsyth 3926*37da2899SCharles.Forsyth #endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ 3927*37da2899SCharles.Forsyth 3928*37da2899SCharles.Forsyth 3929*37da2899SCharles.Forsyth /*************************************************************************/ 3930*37da2899SCharles.Forsyth /* */ 3931*37da2899SCharles.Forsyth /* The following functions are called as is within the switch statement. */ 3932*37da2899SCharles.Forsyth /* */ 3933*37da2899SCharles.Forsyth /*************************************************************************/ 3934*37da2899SCharles.Forsyth 3935*37da2899SCharles.Forsyth 3936*37da2899SCharles.Forsyth /*************************************************************************/ 3937*37da2899SCharles.Forsyth /* */ 3938*37da2899SCharles.Forsyth /* MINDEX[]: Move INDEXed element */ 3939*37da2899SCharles.Forsyth /* Opcode range: 0x26 */ 3940*37da2899SCharles.Forsyth /* Stack: int32? --> StkElt */ 3941*37da2899SCharles.Forsyth /* */ 3942*37da2899SCharles.Forsyth static void Ins_MINDEX(INS_ARG)3943*37da2899SCharles.Forsyth Ins_MINDEX( INS_ARG ) 3944*37da2899SCharles.Forsyth { 3945*37da2899SCharles.Forsyth FT_Long L, K; 3946*37da2899SCharles.Forsyth 3947*37da2899SCharles.Forsyth 3948*37da2899SCharles.Forsyth L = args[0]; 3949*37da2899SCharles.Forsyth 3950*37da2899SCharles.Forsyth if ( L <= 0 || L > CUR.args ) 3951*37da2899SCharles.Forsyth { 3952*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 3953*37da2899SCharles.Forsyth return; 3954*37da2899SCharles.Forsyth } 3955*37da2899SCharles.Forsyth 3956*37da2899SCharles.Forsyth K = CUR.stack[CUR.args - L]; 3957*37da2899SCharles.Forsyth 3958*37da2899SCharles.Forsyth FT_MEM_MOVE( &CUR.stack[CUR.args - L ], 3959*37da2899SCharles.Forsyth &CUR.stack[CUR.args - L + 1], 3960*37da2899SCharles.Forsyth ( L - 1 ) * sizeof ( FT_Long ) ); 3961*37da2899SCharles.Forsyth 3962*37da2899SCharles.Forsyth CUR.stack[CUR.args - 1] = K; 3963*37da2899SCharles.Forsyth } 3964*37da2899SCharles.Forsyth 3965*37da2899SCharles.Forsyth 3966*37da2899SCharles.Forsyth /*************************************************************************/ 3967*37da2899SCharles.Forsyth /* */ 3968*37da2899SCharles.Forsyth /* ROLL[]: ROLL top three elements */ 3969*37da2899SCharles.Forsyth /* Opcode range: 0x8A */ 3970*37da2899SCharles.Forsyth /* Stack: 3 * StkElt --> 3 * StkElt */ 3971*37da2899SCharles.Forsyth /* */ 3972*37da2899SCharles.Forsyth static void Ins_ROLL(INS_ARG)3973*37da2899SCharles.Forsyth Ins_ROLL( INS_ARG ) 3974*37da2899SCharles.Forsyth { 3975*37da2899SCharles.Forsyth FT_Long A, B, C; 3976*37da2899SCharles.Forsyth 3977*37da2899SCharles.Forsyth FT_UNUSED_EXEC; 3978*37da2899SCharles.Forsyth 3979*37da2899SCharles.Forsyth 3980*37da2899SCharles.Forsyth A = args[2]; 3981*37da2899SCharles.Forsyth B = args[1]; 3982*37da2899SCharles.Forsyth C = args[0]; 3983*37da2899SCharles.Forsyth 3984*37da2899SCharles.Forsyth args[2] = C; 3985*37da2899SCharles.Forsyth args[1] = A; 3986*37da2899SCharles.Forsyth args[0] = B; 3987*37da2899SCharles.Forsyth } 3988*37da2899SCharles.Forsyth 3989*37da2899SCharles.Forsyth 3990*37da2899SCharles.Forsyth /*************************************************************************/ 3991*37da2899SCharles.Forsyth /* */ 3992*37da2899SCharles.Forsyth /* MANAGING THE FLOW OF CONTROL */ 3993*37da2899SCharles.Forsyth /* */ 3994*37da2899SCharles.Forsyth /* Instructions appear in the specification's order. */ 3995*37da2899SCharles.Forsyth /* */ 3996*37da2899SCharles.Forsyth /*************************************************************************/ 3997*37da2899SCharles.Forsyth 3998*37da2899SCharles.Forsyth 3999*37da2899SCharles.Forsyth static FT_Bool SkipCode(EXEC_OP)4000*37da2899SCharles.Forsyth SkipCode( EXEC_OP ) 4001*37da2899SCharles.Forsyth { 4002*37da2899SCharles.Forsyth CUR.IP += CUR.length; 4003*37da2899SCharles.Forsyth 4004*37da2899SCharles.Forsyth if ( CUR.IP < CUR.codeSize ) 4005*37da2899SCharles.Forsyth { 4006*37da2899SCharles.Forsyth CUR.opcode = CUR.code[CUR.IP]; 4007*37da2899SCharles.Forsyth 4008*37da2899SCharles.Forsyth CUR.length = opcode_length[CUR.opcode]; 4009*37da2899SCharles.Forsyth if ( CUR.length < 0 ) 4010*37da2899SCharles.Forsyth { 4011*37da2899SCharles.Forsyth if ( CUR.IP + 1 > CUR.codeSize ) 4012*37da2899SCharles.Forsyth goto Fail_Overflow; 4013*37da2899SCharles.Forsyth CUR.length = CUR.code[CUR.IP + 1] + 2; 4014*37da2899SCharles.Forsyth } 4015*37da2899SCharles.Forsyth 4016*37da2899SCharles.Forsyth if ( CUR.IP + CUR.length <= CUR.codeSize ) 4017*37da2899SCharles.Forsyth return SUCCESS; 4018*37da2899SCharles.Forsyth } 4019*37da2899SCharles.Forsyth 4020*37da2899SCharles.Forsyth Fail_Overflow: 4021*37da2899SCharles.Forsyth CUR.error = TT_Err_Code_Overflow; 4022*37da2899SCharles.Forsyth return FAILURE; 4023*37da2899SCharles.Forsyth } 4024*37da2899SCharles.Forsyth 4025*37da2899SCharles.Forsyth 4026*37da2899SCharles.Forsyth /*************************************************************************/ 4027*37da2899SCharles.Forsyth /* */ 4028*37da2899SCharles.Forsyth /* IF[]: IF test */ 4029*37da2899SCharles.Forsyth /* Opcode range: 0x58 */ 4030*37da2899SCharles.Forsyth /* Stack: StkElt --> */ 4031*37da2899SCharles.Forsyth /* */ 4032*37da2899SCharles.Forsyth static void Ins_IF(INS_ARG)4033*37da2899SCharles.Forsyth Ins_IF( INS_ARG ) 4034*37da2899SCharles.Forsyth { 4035*37da2899SCharles.Forsyth FT_Int nIfs; 4036*37da2899SCharles.Forsyth FT_Bool Out; 4037*37da2899SCharles.Forsyth 4038*37da2899SCharles.Forsyth 4039*37da2899SCharles.Forsyth if ( args[0] != 0 ) 4040*37da2899SCharles.Forsyth return; 4041*37da2899SCharles.Forsyth 4042*37da2899SCharles.Forsyth nIfs = 1; 4043*37da2899SCharles.Forsyth Out = 0; 4044*37da2899SCharles.Forsyth 4045*37da2899SCharles.Forsyth do 4046*37da2899SCharles.Forsyth { 4047*37da2899SCharles.Forsyth if ( SKIP_Code() == FAILURE ) 4048*37da2899SCharles.Forsyth return; 4049*37da2899SCharles.Forsyth 4050*37da2899SCharles.Forsyth switch ( CUR.opcode ) 4051*37da2899SCharles.Forsyth { 4052*37da2899SCharles.Forsyth case 0x58: /* IF */ 4053*37da2899SCharles.Forsyth nIfs++; 4054*37da2899SCharles.Forsyth break; 4055*37da2899SCharles.Forsyth 4056*37da2899SCharles.Forsyth case 0x1B: /* ELSE */ 4057*37da2899SCharles.Forsyth Out = FT_BOOL( nIfs == 1 ); 4058*37da2899SCharles.Forsyth break; 4059*37da2899SCharles.Forsyth 4060*37da2899SCharles.Forsyth case 0x59: /* EIF */ 4061*37da2899SCharles.Forsyth nIfs--; 4062*37da2899SCharles.Forsyth Out = FT_BOOL( nIfs == 0 ); 4063*37da2899SCharles.Forsyth break; 4064*37da2899SCharles.Forsyth } 4065*37da2899SCharles.Forsyth } while ( Out == 0 ); 4066*37da2899SCharles.Forsyth } 4067*37da2899SCharles.Forsyth 4068*37da2899SCharles.Forsyth 4069*37da2899SCharles.Forsyth /*************************************************************************/ 4070*37da2899SCharles.Forsyth /* */ 4071*37da2899SCharles.Forsyth /* ELSE[]: ELSE */ 4072*37da2899SCharles.Forsyth /* Opcode range: 0x1B */ 4073*37da2899SCharles.Forsyth /* Stack: --> */ 4074*37da2899SCharles.Forsyth /* */ 4075*37da2899SCharles.Forsyth static void Ins_ELSE(INS_ARG)4076*37da2899SCharles.Forsyth Ins_ELSE( INS_ARG ) 4077*37da2899SCharles.Forsyth { 4078*37da2899SCharles.Forsyth FT_Int nIfs; 4079*37da2899SCharles.Forsyth 4080*37da2899SCharles.Forsyth FT_UNUSED_ARG; 4081*37da2899SCharles.Forsyth 4082*37da2899SCharles.Forsyth 4083*37da2899SCharles.Forsyth nIfs = 1; 4084*37da2899SCharles.Forsyth 4085*37da2899SCharles.Forsyth do 4086*37da2899SCharles.Forsyth { 4087*37da2899SCharles.Forsyth if ( SKIP_Code() == FAILURE ) 4088*37da2899SCharles.Forsyth return; 4089*37da2899SCharles.Forsyth 4090*37da2899SCharles.Forsyth switch ( CUR.opcode ) 4091*37da2899SCharles.Forsyth { 4092*37da2899SCharles.Forsyth case 0x58: /* IF */ 4093*37da2899SCharles.Forsyth nIfs++; 4094*37da2899SCharles.Forsyth break; 4095*37da2899SCharles.Forsyth 4096*37da2899SCharles.Forsyth case 0x59: /* EIF */ 4097*37da2899SCharles.Forsyth nIfs--; 4098*37da2899SCharles.Forsyth break; 4099*37da2899SCharles.Forsyth } 4100*37da2899SCharles.Forsyth } while ( nIfs != 0 ); 4101*37da2899SCharles.Forsyth } 4102*37da2899SCharles.Forsyth 4103*37da2899SCharles.Forsyth 4104*37da2899SCharles.Forsyth /*************************************************************************/ 4105*37da2899SCharles.Forsyth /* */ 4106*37da2899SCharles.Forsyth /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ 4107*37da2899SCharles.Forsyth /* */ 4108*37da2899SCharles.Forsyth /* Instructions appear in the specification's order. */ 4109*37da2899SCharles.Forsyth /* */ 4110*37da2899SCharles.Forsyth /*************************************************************************/ 4111*37da2899SCharles.Forsyth 4112*37da2899SCharles.Forsyth 4113*37da2899SCharles.Forsyth /*************************************************************************/ 4114*37da2899SCharles.Forsyth /* */ 4115*37da2899SCharles.Forsyth /* FDEF[]: Function DEFinition */ 4116*37da2899SCharles.Forsyth /* Opcode range: 0x2C */ 4117*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 4118*37da2899SCharles.Forsyth /* */ 4119*37da2899SCharles.Forsyth static void Ins_FDEF(INS_ARG)4120*37da2899SCharles.Forsyth Ins_FDEF( INS_ARG ) 4121*37da2899SCharles.Forsyth { 4122*37da2899SCharles.Forsyth FT_ULong n; 4123*37da2899SCharles.Forsyth TT_DefRecord* rec; 4124*37da2899SCharles.Forsyth TT_DefRecord* limit; 4125*37da2899SCharles.Forsyth 4126*37da2899SCharles.Forsyth 4127*37da2899SCharles.Forsyth /* some font programs are broken enough to redefine functions! */ 4128*37da2899SCharles.Forsyth /* We will then parse the current table. */ 4129*37da2899SCharles.Forsyth 4130*37da2899SCharles.Forsyth rec = CUR.FDefs; 4131*37da2899SCharles.Forsyth limit = rec + CUR.numFDefs; 4132*37da2899SCharles.Forsyth n = args[0]; 4133*37da2899SCharles.Forsyth 4134*37da2899SCharles.Forsyth for ( ; rec < limit; rec++ ) 4135*37da2899SCharles.Forsyth { 4136*37da2899SCharles.Forsyth if ( rec->opc == n ) 4137*37da2899SCharles.Forsyth break; 4138*37da2899SCharles.Forsyth } 4139*37da2899SCharles.Forsyth 4140*37da2899SCharles.Forsyth if ( rec == limit ) 4141*37da2899SCharles.Forsyth { 4142*37da2899SCharles.Forsyth /* check that there is enough room for new functions */ 4143*37da2899SCharles.Forsyth if ( CUR.numFDefs >= CUR.maxFDefs ) 4144*37da2899SCharles.Forsyth { 4145*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Many_Function_Defs; 4146*37da2899SCharles.Forsyth return; 4147*37da2899SCharles.Forsyth } 4148*37da2899SCharles.Forsyth CUR.numFDefs++; 4149*37da2899SCharles.Forsyth } 4150*37da2899SCharles.Forsyth 4151*37da2899SCharles.Forsyth rec->range = CUR.curRange; 4152*37da2899SCharles.Forsyth rec->opc = n; 4153*37da2899SCharles.Forsyth rec->start = CUR.IP + 1; 4154*37da2899SCharles.Forsyth rec->active = TRUE; 4155*37da2899SCharles.Forsyth 4156*37da2899SCharles.Forsyth if ( n > CUR.maxFunc ) 4157*37da2899SCharles.Forsyth CUR.maxFunc = n; 4158*37da2899SCharles.Forsyth 4159*37da2899SCharles.Forsyth /* Now skip the whole function definition. */ 4160*37da2899SCharles.Forsyth /* We don't allow nested IDEFS & FDEFs. */ 4161*37da2899SCharles.Forsyth 4162*37da2899SCharles.Forsyth while ( SKIP_Code() == SUCCESS ) 4163*37da2899SCharles.Forsyth { 4164*37da2899SCharles.Forsyth switch ( CUR.opcode ) 4165*37da2899SCharles.Forsyth { 4166*37da2899SCharles.Forsyth case 0x89: /* IDEF */ 4167*37da2899SCharles.Forsyth case 0x2C: /* FDEF */ 4168*37da2899SCharles.Forsyth CUR.error = TT_Err_Nested_DEFS; 4169*37da2899SCharles.Forsyth return; 4170*37da2899SCharles.Forsyth 4171*37da2899SCharles.Forsyth case 0x2D: /* ENDF */ 4172*37da2899SCharles.Forsyth return; 4173*37da2899SCharles.Forsyth } 4174*37da2899SCharles.Forsyth } 4175*37da2899SCharles.Forsyth } 4176*37da2899SCharles.Forsyth 4177*37da2899SCharles.Forsyth 4178*37da2899SCharles.Forsyth /*************************************************************************/ 4179*37da2899SCharles.Forsyth /* */ 4180*37da2899SCharles.Forsyth /* ENDF[]: END Function definition */ 4181*37da2899SCharles.Forsyth /* Opcode range: 0x2D */ 4182*37da2899SCharles.Forsyth /* Stack: --> */ 4183*37da2899SCharles.Forsyth /* */ 4184*37da2899SCharles.Forsyth static void Ins_ENDF(INS_ARG)4185*37da2899SCharles.Forsyth Ins_ENDF( INS_ARG ) 4186*37da2899SCharles.Forsyth { 4187*37da2899SCharles.Forsyth TT_CallRec* pRec; 4188*37da2899SCharles.Forsyth 4189*37da2899SCharles.Forsyth FT_UNUSED_ARG; 4190*37da2899SCharles.Forsyth 4191*37da2899SCharles.Forsyth 4192*37da2899SCharles.Forsyth if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ 4193*37da2899SCharles.Forsyth { 4194*37da2899SCharles.Forsyth CUR.error = TT_Err_ENDF_In_Exec_Stream; 4195*37da2899SCharles.Forsyth return; 4196*37da2899SCharles.Forsyth } 4197*37da2899SCharles.Forsyth 4198*37da2899SCharles.Forsyth CUR.callTop--; 4199*37da2899SCharles.Forsyth 4200*37da2899SCharles.Forsyth pRec = &CUR.callStack[CUR.callTop]; 4201*37da2899SCharles.Forsyth 4202*37da2899SCharles.Forsyth pRec->Cur_Count--; 4203*37da2899SCharles.Forsyth 4204*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 4205*37da2899SCharles.Forsyth 4206*37da2899SCharles.Forsyth if ( pRec->Cur_Count > 0 ) 4207*37da2899SCharles.Forsyth { 4208*37da2899SCharles.Forsyth CUR.callTop++; 4209*37da2899SCharles.Forsyth CUR.IP = pRec->Cur_Restart; 4210*37da2899SCharles.Forsyth } 4211*37da2899SCharles.Forsyth else 4212*37da2899SCharles.Forsyth /* Loop through the current function */ 4213*37da2899SCharles.Forsyth INS_Goto_CodeRange( pRec->Caller_Range, 4214*37da2899SCharles.Forsyth pRec->Caller_IP ); 4215*37da2899SCharles.Forsyth 4216*37da2899SCharles.Forsyth /* Exit the current call frame. */ 4217*37da2899SCharles.Forsyth 4218*37da2899SCharles.Forsyth /* NOTE: If the last intruction of a program is a */ 4219*37da2899SCharles.Forsyth /* CALL or LOOPCALL, the return address is */ 4220*37da2899SCharles.Forsyth /* always out of the code range. This is a */ 4221*37da2899SCharles.Forsyth /* valid address, and it is why we do not test */ 4222*37da2899SCharles.Forsyth /* the result of Ins_Goto_CodeRange() here! */ 4223*37da2899SCharles.Forsyth } 4224*37da2899SCharles.Forsyth 4225*37da2899SCharles.Forsyth 4226*37da2899SCharles.Forsyth /*************************************************************************/ 4227*37da2899SCharles.Forsyth /* */ 4228*37da2899SCharles.Forsyth /* CALL[]: CALL function */ 4229*37da2899SCharles.Forsyth /* Opcode range: 0x2B */ 4230*37da2899SCharles.Forsyth /* Stack: uint32? --> */ 4231*37da2899SCharles.Forsyth /* */ 4232*37da2899SCharles.Forsyth static void Ins_CALL(INS_ARG)4233*37da2899SCharles.Forsyth Ins_CALL( INS_ARG ) 4234*37da2899SCharles.Forsyth { 4235*37da2899SCharles.Forsyth FT_ULong F; 4236*37da2899SCharles.Forsyth TT_CallRec* pCrec; 4237*37da2899SCharles.Forsyth TT_DefRecord* def; 4238*37da2899SCharles.Forsyth 4239*37da2899SCharles.Forsyth 4240*37da2899SCharles.Forsyth /* first of all, check the index */ 4241*37da2899SCharles.Forsyth 4242*37da2899SCharles.Forsyth F = args[0]; 4243*37da2899SCharles.Forsyth if ( BOUNDS( F, CUR.maxFunc + 1 ) ) 4244*37da2899SCharles.Forsyth goto Fail; 4245*37da2899SCharles.Forsyth 4246*37da2899SCharles.Forsyth /* Except for some old Apple fonts, all functions in a TrueType */ 4247*37da2899SCharles.Forsyth /* font are defined in increasing order, starting from 0. This */ 4248*37da2899SCharles.Forsyth /* means that we normally have */ 4249*37da2899SCharles.Forsyth /* */ 4250*37da2899SCharles.Forsyth /* CUR.maxFunc+1 == CUR.numFDefs */ 4251*37da2899SCharles.Forsyth /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ 4252*37da2899SCharles.Forsyth /* */ 4253*37da2899SCharles.Forsyth /* If this isn't true, we need to look up the function table. */ 4254*37da2899SCharles.Forsyth 4255*37da2899SCharles.Forsyth def = CUR.FDefs + F; 4256*37da2899SCharles.Forsyth if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) 4257*37da2899SCharles.Forsyth { 4258*37da2899SCharles.Forsyth /* look up the FDefs table */ 4259*37da2899SCharles.Forsyth TT_DefRecord* limit; 4260*37da2899SCharles.Forsyth 4261*37da2899SCharles.Forsyth 4262*37da2899SCharles.Forsyth def = CUR.FDefs; 4263*37da2899SCharles.Forsyth limit = def + CUR.numFDefs; 4264*37da2899SCharles.Forsyth 4265*37da2899SCharles.Forsyth while ( def < limit && def->opc != F ) 4266*37da2899SCharles.Forsyth def++; 4267*37da2899SCharles.Forsyth 4268*37da2899SCharles.Forsyth if ( def == limit ) 4269*37da2899SCharles.Forsyth goto Fail; 4270*37da2899SCharles.Forsyth } 4271*37da2899SCharles.Forsyth 4272*37da2899SCharles.Forsyth /* check that the function is active */ 4273*37da2899SCharles.Forsyth if ( !def->active ) 4274*37da2899SCharles.Forsyth goto Fail; 4275*37da2899SCharles.Forsyth 4276*37da2899SCharles.Forsyth /* check the call stack */ 4277*37da2899SCharles.Forsyth if ( CUR.callTop >= CUR.callSize ) 4278*37da2899SCharles.Forsyth { 4279*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4280*37da2899SCharles.Forsyth return; 4281*37da2899SCharles.Forsyth } 4282*37da2899SCharles.Forsyth 4283*37da2899SCharles.Forsyth pCrec = CUR.callStack + CUR.callTop; 4284*37da2899SCharles.Forsyth 4285*37da2899SCharles.Forsyth pCrec->Caller_Range = CUR.curRange; 4286*37da2899SCharles.Forsyth pCrec->Caller_IP = CUR.IP + 1; 4287*37da2899SCharles.Forsyth pCrec->Cur_Count = 1; 4288*37da2899SCharles.Forsyth pCrec->Cur_Restart = def->start; 4289*37da2899SCharles.Forsyth 4290*37da2899SCharles.Forsyth CUR.callTop++; 4291*37da2899SCharles.Forsyth 4292*37da2899SCharles.Forsyth INS_Goto_CodeRange( def->range, 4293*37da2899SCharles.Forsyth def->start ); 4294*37da2899SCharles.Forsyth 4295*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 4296*37da2899SCharles.Forsyth return; 4297*37da2899SCharles.Forsyth 4298*37da2899SCharles.Forsyth Fail: 4299*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4300*37da2899SCharles.Forsyth } 4301*37da2899SCharles.Forsyth 4302*37da2899SCharles.Forsyth 4303*37da2899SCharles.Forsyth /*************************************************************************/ 4304*37da2899SCharles.Forsyth /* */ 4305*37da2899SCharles.Forsyth /* LOOPCALL[]: LOOP and CALL function */ 4306*37da2899SCharles.Forsyth /* Opcode range: 0x2A */ 4307*37da2899SCharles.Forsyth /* Stack: uint32? Eint16? --> */ 4308*37da2899SCharles.Forsyth /* */ 4309*37da2899SCharles.Forsyth static void Ins_LOOPCALL(INS_ARG)4310*37da2899SCharles.Forsyth Ins_LOOPCALL( INS_ARG ) 4311*37da2899SCharles.Forsyth { 4312*37da2899SCharles.Forsyth FT_ULong F; 4313*37da2899SCharles.Forsyth TT_CallRec* pCrec; 4314*37da2899SCharles.Forsyth TT_DefRecord* def; 4315*37da2899SCharles.Forsyth 4316*37da2899SCharles.Forsyth 4317*37da2899SCharles.Forsyth /* first of all, check the index */ 4318*37da2899SCharles.Forsyth F = args[1]; 4319*37da2899SCharles.Forsyth if ( BOUNDS( F, CUR.maxFunc + 1 ) ) 4320*37da2899SCharles.Forsyth goto Fail; 4321*37da2899SCharles.Forsyth 4322*37da2899SCharles.Forsyth /* Except for some old Apple fonts, all functions in a TrueType */ 4323*37da2899SCharles.Forsyth /* font are defined in increasing order, starting from 0. This */ 4324*37da2899SCharles.Forsyth /* means that we normally have */ 4325*37da2899SCharles.Forsyth /* */ 4326*37da2899SCharles.Forsyth /* CUR.maxFunc+1 == CUR.numFDefs */ 4327*37da2899SCharles.Forsyth /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ 4328*37da2899SCharles.Forsyth /* */ 4329*37da2899SCharles.Forsyth /* If this isn't true, we need to look up the function table. */ 4330*37da2899SCharles.Forsyth 4331*37da2899SCharles.Forsyth def = CUR.FDefs + F; 4332*37da2899SCharles.Forsyth if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) 4333*37da2899SCharles.Forsyth { 4334*37da2899SCharles.Forsyth /* look up the FDefs table */ 4335*37da2899SCharles.Forsyth TT_DefRecord* limit; 4336*37da2899SCharles.Forsyth 4337*37da2899SCharles.Forsyth 4338*37da2899SCharles.Forsyth def = CUR.FDefs; 4339*37da2899SCharles.Forsyth limit = def + CUR.numFDefs; 4340*37da2899SCharles.Forsyth 4341*37da2899SCharles.Forsyth while ( def < limit && def->opc != F ) 4342*37da2899SCharles.Forsyth def++; 4343*37da2899SCharles.Forsyth 4344*37da2899SCharles.Forsyth if ( def == limit ) 4345*37da2899SCharles.Forsyth goto Fail; 4346*37da2899SCharles.Forsyth } 4347*37da2899SCharles.Forsyth 4348*37da2899SCharles.Forsyth /* check that the function is active */ 4349*37da2899SCharles.Forsyth if ( !def->active ) 4350*37da2899SCharles.Forsyth goto Fail; 4351*37da2899SCharles.Forsyth 4352*37da2899SCharles.Forsyth /* check stack */ 4353*37da2899SCharles.Forsyth if ( CUR.callTop >= CUR.callSize ) 4354*37da2899SCharles.Forsyth { 4355*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4356*37da2899SCharles.Forsyth return; 4357*37da2899SCharles.Forsyth } 4358*37da2899SCharles.Forsyth 4359*37da2899SCharles.Forsyth if ( args[0] > 0 ) 4360*37da2899SCharles.Forsyth { 4361*37da2899SCharles.Forsyth pCrec = CUR.callStack + CUR.callTop; 4362*37da2899SCharles.Forsyth 4363*37da2899SCharles.Forsyth pCrec->Caller_Range = CUR.curRange; 4364*37da2899SCharles.Forsyth pCrec->Caller_IP = CUR.IP + 1; 4365*37da2899SCharles.Forsyth pCrec->Cur_Count = (FT_Int)args[0]; 4366*37da2899SCharles.Forsyth pCrec->Cur_Restart = def->start; 4367*37da2899SCharles.Forsyth 4368*37da2899SCharles.Forsyth CUR.callTop++; 4369*37da2899SCharles.Forsyth 4370*37da2899SCharles.Forsyth INS_Goto_CodeRange( def->range, def->start ); 4371*37da2899SCharles.Forsyth 4372*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 4373*37da2899SCharles.Forsyth } 4374*37da2899SCharles.Forsyth return; 4375*37da2899SCharles.Forsyth 4376*37da2899SCharles.Forsyth Fail: 4377*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4378*37da2899SCharles.Forsyth } 4379*37da2899SCharles.Forsyth 4380*37da2899SCharles.Forsyth 4381*37da2899SCharles.Forsyth /*************************************************************************/ 4382*37da2899SCharles.Forsyth /* */ 4383*37da2899SCharles.Forsyth /* IDEF[]: Instruction DEFinition */ 4384*37da2899SCharles.Forsyth /* Opcode range: 0x89 */ 4385*37da2899SCharles.Forsyth /* Stack: Eint8 --> */ 4386*37da2899SCharles.Forsyth /* */ 4387*37da2899SCharles.Forsyth static void Ins_IDEF(INS_ARG)4388*37da2899SCharles.Forsyth Ins_IDEF( INS_ARG ) 4389*37da2899SCharles.Forsyth { 4390*37da2899SCharles.Forsyth TT_DefRecord* def; 4391*37da2899SCharles.Forsyth TT_DefRecord* limit; 4392*37da2899SCharles.Forsyth 4393*37da2899SCharles.Forsyth 4394*37da2899SCharles.Forsyth /* First of all, look for the same function in our table */ 4395*37da2899SCharles.Forsyth 4396*37da2899SCharles.Forsyth def = CUR.IDefs; 4397*37da2899SCharles.Forsyth limit = def + CUR.numIDefs; 4398*37da2899SCharles.Forsyth 4399*37da2899SCharles.Forsyth for ( ; def < limit; def++ ) 4400*37da2899SCharles.Forsyth if ( def->opc == (FT_ULong)args[0] ) 4401*37da2899SCharles.Forsyth break; 4402*37da2899SCharles.Forsyth 4403*37da2899SCharles.Forsyth if ( def == limit ) 4404*37da2899SCharles.Forsyth { 4405*37da2899SCharles.Forsyth /* check that there is enough room for a new instruction */ 4406*37da2899SCharles.Forsyth if ( CUR.numIDefs >= CUR.maxIDefs ) 4407*37da2899SCharles.Forsyth { 4408*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Many_Instruction_Defs; 4409*37da2899SCharles.Forsyth return; 4410*37da2899SCharles.Forsyth } 4411*37da2899SCharles.Forsyth CUR.numIDefs++; 4412*37da2899SCharles.Forsyth } 4413*37da2899SCharles.Forsyth 4414*37da2899SCharles.Forsyth def->opc = args[0]; 4415*37da2899SCharles.Forsyth def->start = CUR.IP+1; 4416*37da2899SCharles.Forsyth def->range = CUR.curRange; 4417*37da2899SCharles.Forsyth def->active = TRUE; 4418*37da2899SCharles.Forsyth 4419*37da2899SCharles.Forsyth if ( (FT_ULong)args[0] > CUR.maxIns ) 4420*37da2899SCharles.Forsyth CUR.maxIns = args[0]; 4421*37da2899SCharles.Forsyth 4422*37da2899SCharles.Forsyth /* Now skip the whole function definition. */ 4423*37da2899SCharles.Forsyth /* We don't allow nested IDEFs & FDEFs. */ 4424*37da2899SCharles.Forsyth 4425*37da2899SCharles.Forsyth while ( SKIP_Code() == SUCCESS ) 4426*37da2899SCharles.Forsyth { 4427*37da2899SCharles.Forsyth switch ( CUR.opcode ) 4428*37da2899SCharles.Forsyth { 4429*37da2899SCharles.Forsyth case 0x89: /* IDEF */ 4430*37da2899SCharles.Forsyth case 0x2C: /* FDEF */ 4431*37da2899SCharles.Forsyth CUR.error = TT_Err_Nested_DEFS; 4432*37da2899SCharles.Forsyth return; 4433*37da2899SCharles.Forsyth case 0x2D: /* ENDF */ 4434*37da2899SCharles.Forsyth return; 4435*37da2899SCharles.Forsyth } 4436*37da2899SCharles.Forsyth } 4437*37da2899SCharles.Forsyth } 4438*37da2899SCharles.Forsyth 4439*37da2899SCharles.Forsyth 4440*37da2899SCharles.Forsyth /*************************************************************************/ 4441*37da2899SCharles.Forsyth /* */ 4442*37da2899SCharles.Forsyth /* PUSHING DATA ONTO THE INTERPRETER STACK */ 4443*37da2899SCharles.Forsyth /* */ 4444*37da2899SCharles.Forsyth /* Instructions appear in the specification's order. */ 4445*37da2899SCharles.Forsyth /* */ 4446*37da2899SCharles.Forsyth /*************************************************************************/ 4447*37da2899SCharles.Forsyth 4448*37da2899SCharles.Forsyth 4449*37da2899SCharles.Forsyth /*************************************************************************/ 4450*37da2899SCharles.Forsyth /* */ 4451*37da2899SCharles.Forsyth /* NPUSHB[]: PUSH N Bytes */ 4452*37da2899SCharles.Forsyth /* Opcode range: 0x40 */ 4453*37da2899SCharles.Forsyth /* Stack: --> uint32... */ 4454*37da2899SCharles.Forsyth /* */ 4455*37da2899SCharles.Forsyth static void Ins_NPUSHB(INS_ARG)4456*37da2899SCharles.Forsyth Ins_NPUSHB( INS_ARG ) 4457*37da2899SCharles.Forsyth { 4458*37da2899SCharles.Forsyth FT_UShort L, K; 4459*37da2899SCharles.Forsyth 4460*37da2899SCharles.Forsyth 4461*37da2899SCharles.Forsyth L = (FT_UShort)CUR.code[CUR.IP + 1]; 4462*37da2899SCharles.Forsyth 4463*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4464*37da2899SCharles.Forsyth { 4465*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4466*37da2899SCharles.Forsyth return; 4467*37da2899SCharles.Forsyth } 4468*37da2899SCharles.Forsyth 4469*37da2899SCharles.Forsyth for ( K = 1; K <= L; K++ ) 4470*37da2899SCharles.Forsyth args[K - 1] = CUR.code[CUR.IP + K + 1]; 4471*37da2899SCharles.Forsyth 4472*37da2899SCharles.Forsyth CUR.new_top += L; 4473*37da2899SCharles.Forsyth } 4474*37da2899SCharles.Forsyth 4475*37da2899SCharles.Forsyth 4476*37da2899SCharles.Forsyth /*************************************************************************/ 4477*37da2899SCharles.Forsyth /* */ 4478*37da2899SCharles.Forsyth /* NPUSHW[]: PUSH N Words */ 4479*37da2899SCharles.Forsyth /* Opcode range: 0x41 */ 4480*37da2899SCharles.Forsyth /* Stack: --> int32... */ 4481*37da2899SCharles.Forsyth /* */ 4482*37da2899SCharles.Forsyth static void Ins_NPUSHW(INS_ARG)4483*37da2899SCharles.Forsyth Ins_NPUSHW( INS_ARG ) 4484*37da2899SCharles.Forsyth { 4485*37da2899SCharles.Forsyth FT_UShort L, K; 4486*37da2899SCharles.Forsyth 4487*37da2899SCharles.Forsyth 4488*37da2899SCharles.Forsyth L = (FT_UShort)CUR.code[CUR.IP + 1]; 4489*37da2899SCharles.Forsyth 4490*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4491*37da2899SCharles.Forsyth { 4492*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4493*37da2899SCharles.Forsyth return; 4494*37da2899SCharles.Forsyth } 4495*37da2899SCharles.Forsyth 4496*37da2899SCharles.Forsyth CUR.IP += 2; 4497*37da2899SCharles.Forsyth 4498*37da2899SCharles.Forsyth for ( K = 0; K < L; K++ ) 4499*37da2899SCharles.Forsyth args[K] = GET_ShortIns(); 4500*37da2899SCharles.Forsyth 4501*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 4502*37da2899SCharles.Forsyth CUR.new_top += L; 4503*37da2899SCharles.Forsyth } 4504*37da2899SCharles.Forsyth 4505*37da2899SCharles.Forsyth 4506*37da2899SCharles.Forsyth /*************************************************************************/ 4507*37da2899SCharles.Forsyth /* */ 4508*37da2899SCharles.Forsyth /* PUSHB[abc]: PUSH Bytes */ 4509*37da2899SCharles.Forsyth /* Opcode range: 0xB0-0xB7 */ 4510*37da2899SCharles.Forsyth /* Stack: --> uint32... */ 4511*37da2899SCharles.Forsyth /* */ 4512*37da2899SCharles.Forsyth static void Ins_PUSHB(INS_ARG)4513*37da2899SCharles.Forsyth Ins_PUSHB( INS_ARG ) 4514*37da2899SCharles.Forsyth { 4515*37da2899SCharles.Forsyth FT_UShort L, K; 4516*37da2899SCharles.Forsyth 4517*37da2899SCharles.Forsyth 4518*37da2899SCharles.Forsyth L = (FT_UShort)(CUR.opcode - 0xB0 + 1); 4519*37da2899SCharles.Forsyth 4520*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4521*37da2899SCharles.Forsyth { 4522*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4523*37da2899SCharles.Forsyth return; 4524*37da2899SCharles.Forsyth } 4525*37da2899SCharles.Forsyth 4526*37da2899SCharles.Forsyth for ( K = 1; K <= L; K++ ) 4527*37da2899SCharles.Forsyth args[K - 1] = CUR.code[CUR.IP + K]; 4528*37da2899SCharles.Forsyth } 4529*37da2899SCharles.Forsyth 4530*37da2899SCharles.Forsyth 4531*37da2899SCharles.Forsyth /*************************************************************************/ 4532*37da2899SCharles.Forsyth /* */ 4533*37da2899SCharles.Forsyth /* PUSHW[abc]: PUSH Words */ 4534*37da2899SCharles.Forsyth /* Opcode range: 0xB8-0xBF */ 4535*37da2899SCharles.Forsyth /* Stack: --> int32... */ 4536*37da2899SCharles.Forsyth /* */ 4537*37da2899SCharles.Forsyth static void Ins_PUSHW(INS_ARG)4538*37da2899SCharles.Forsyth Ins_PUSHW( INS_ARG ) 4539*37da2899SCharles.Forsyth { 4540*37da2899SCharles.Forsyth FT_UShort L, K; 4541*37da2899SCharles.Forsyth 4542*37da2899SCharles.Forsyth 4543*37da2899SCharles.Forsyth L = (FT_UShort)(CUR.opcode - 0xB8 + 1); 4544*37da2899SCharles.Forsyth 4545*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4546*37da2899SCharles.Forsyth { 4547*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 4548*37da2899SCharles.Forsyth return; 4549*37da2899SCharles.Forsyth } 4550*37da2899SCharles.Forsyth 4551*37da2899SCharles.Forsyth CUR.IP++; 4552*37da2899SCharles.Forsyth 4553*37da2899SCharles.Forsyth for ( K = 0; K < L; K++ ) 4554*37da2899SCharles.Forsyth args[K] = GET_ShortIns(); 4555*37da2899SCharles.Forsyth 4556*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 4557*37da2899SCharles.Forsyth } 4558*37da2899SCharles.Forsyth 4559*37da2899SCharles.Forsyth 4560*37da2899SCharles.Forsyth /*************************************************************************/ 4561*37da2899SCharles.Forsyth /* */ 4562*37da2899SCharles.Forsyth /* MANAGING THE GRAPHICS STATE */ 4563*37da2899SCharles.Forsyth /* */ 4564*37da2899SCharles.Forsyth /* Instructions appear in the specs' order. */ 4565*37da2899SCharles.Forsyth /* */ 4566*37da2899SCharles.Forsyth /*************************************************************************/ 4567*37da2899SCharles.Forsyth 4568*37da2899SCharles.Forsyth 4569*37da2899SCharles.Forsyth /*************************************************************************/ 4570*37da2899SCharles.Forsyth /* */ 4571*37da2899SCharles.Forsyth /* GC[a]: Get Coordinate projected onto */ 4572*37da2899SCharles.Forsyth /* Opcode range: 0x46-0x47 */ 4573*37da2899SCharles.Forsyth /* Stack: uint32 --> f26.6 */ 4574*37da2899SCharles.Forsyth /* */ 4575*37da2899SCharles.Forsyth /* BULLSHIT: Measures from the original glyph must be taken along the */ 4576*37da2899SCharles.Forsyth /* dual projection vector! */ 4577*37da2899SCharles.Forsyth /* */ 4578*37da2899SCharles.Forsyth static void Ins_GC(INS_ARG)4579*37da2899SCharles.Forsyth Ins_GC( INS_ARG ) 4580*37da2899SCharles.Forsyth { 4581*37da2899SCharles.Forsyth FT_ULong L; 4582*37da2899SCharles.Forsyth FT_F26Dot6 R; 4583*37da2899SCharles.Forsyth 4584*37da2899SCharles.Forsyth 4585*37da2899SCharles.Forsyth L = (FT_ULong)args[0]; 4586*37da2899SCharles.Forsyth 4587*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.zp2.n_points ) ) 4588*37da2899SCharles.Forsyth { 4589*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4590*37da2899SCharles.Forsyth { 4591*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4592*37da2899SCharles.Forsyth return; 4593*37da2899SCharles.Forsyth } 4594*37da2899SCharles.Forsyth else 4595*37da2899SCharles.Forsyth R = 0; 4596*37da2899SCharles.Forsyth } 4597*37da2899SCharles.Forsyth else 4598*37da2899SCharles.Forsyth { 4599*37da2899SCharles.Forsyth if ( CUR.opcode & 1 ) 4600*37da2899SCharles.Forsyth R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector ); 4601*37da2899SCharles.Forsyth else 4602*37da2899SCharles.Forsyth R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); 4603*37da2899SCharles.Forsyth } 4604*37da2899SCharles.Forsyth 4605*37da2899SCharles.Forsyth args[0] = R; 4606*37da2899SCharles.Forsyth } 4607*37da2899SCharles.Forsyth 4608*37da2899SCharles.Forsyth 4609*37da2899SCharles.Forsyth /*************************************************************************/ 4610*37da2899SCharles.Forsyth /* */ 4611*37da2899SCharles.Forsyth /* SCFS[]: Set Coordinate From Stack */ 4612*37da2899SCharles.Forsyth /* Opcode range: 0x48 */ 4613*37da2899SCharles.Forsyth /* Stack: f26.6 uint32 --> */ 4614*37da2899SCharles.Forsyth /* */ 4615*37da2899SCharles.Forsyth /* Formula: */ 4616*37da2899SCharles.Forsyth /* */ 4617*37da2899SCharles.Forsyth /* OA := OA + ( value - OA.p )/( f.p ) * f */ 4618*37da2899SCharles.Forsyth /* */ 4619*37da2899SCharles.Forsyth static void Ins_SCFS(INS_ARG)4620*37da2899SCharles.Forsyth Ins_SCFS( INS_ARG ) 4621*37da2899SCharles.Forsyth { 4622*37da2899SCharles.Forsyth FT_Long K; 4623*37da2899SCharles.Forsyth FT_UShort L; 4624*37da2899SCharles.Forsyth 4625*37da2899SCharles.Forsyth 4626*37da2899SCharles.Forsyth L = (FT_UShort)args[0]; 4627*37da2899SCharles.Forsyth 4628*37da2899SCharles.Forsyth if ( BOUNDS( L, CUR.zp2.n_points ) ) 4629*37da2899SCharles.Forsyth { 4630*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4631*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4632*37da2899SCharles.Forsyth return; 4633*37da2899SCharles.Forsyth } 4634*37da2899SCharles.Forsyth 4635*37da2899SCharles.Forsyth K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); 4636*37da2899SCharles.Forsyth 4637*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp2, L, args[1] - K ); 4638*37da2899SCharles.Forsyth 4639*37da2899SCharles.Forsyth /* not part of the specs, but here for safety */ 4640*37da2899SCharles.Forsyth 4641*37da2899SCharles.Forsyth if ( CUR.GS.gep2 == 0 ) 4642*37da2899SCharles.Forsyth CUR.zp2.org[L] = CUR.zp2.cur[L]; 4643*37da2899SCharles.Forsyth } 4644*37da2899SCharles.Forsyth 4645*37da2899SCharles.Forsyth 4646*37da2899SCharles.Forsyth /*************************************************************************/ 4647*37da2899SCharles.Forsyth /* */ 4648*37da2899SCharles.Forsyth /* MD[a]: Measure Distance */ 4649*37da2899SCharles.Forsyth /* Opcode range: 0x49-0x4A */ 4650*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> f26.6 */ 4651*37da2899SCharles.Forsyth /* */ 4652*37da2899SCharles.Forsyth /* BULLSHIT: Measure taken in the original glyph must be along the dual */ 4653*37da2899SCharles.Forsyth /* projection vector. */ 4654*37da2899SCharles.Forsyth /* */ 4655*37da2899SCharles.Forsyth /* Second BULLSHIT: Flag attributes are inverted! */ 4656*37da2899SCharles.Forsyth /* 0 => measure distance in original outline */ 4657*37da2899SCharles.Forsyth /* 1 => measure distance in grid-fitted outline */ 4658*37da2899SCharles.Forsyth /* */ 4659*37da2899SCharles.Forsyth /* Third one: `zp0 - zp1', and not `zp2 - zp1! */ 4660*37da2899SCharles.Forsyth /* */ 4661*37da2899SCharles.Forsyth static void Ins_MD(INS_ARG)4662*37da2899SCharles.Forsyth Ins_MD( INS_ARG ) 4663*37da2899SCharles.Forsyth { 4664*37da2899SCharles.Forsyth FT_UShort K, L; 4665*37da2899SCharles.Forsyth FT_F26Dot6 D; 4666*37da2899SCharles.Forsyth 4667*37da2899SCharles.Forsyth 4668*37da2899SCharles.Forsyth K = (FT_UShort)args[1]; 4669*37da2899SCharles.Forsyth L = (FT_UShort)args[0]; 4670*37da2899SCharles.Forsyth 4671*37da2899SCharles.Forsyth if( BOUNDS( L, CUR.zp0.n_points ) || 4672*37da2899SCharles.Forsyth BOUNDS( K, CUR.zp1.n_points ) ) 4673*37da2899SCharles.Forsyth { 4674*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4675*37da2899SCharles.Forsyth { 4676*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4677*37da2899SCharles.Forsyth return; 4678*37da2899SCharles.Forsyth } 4679*37da2899SCharles.Forsyth D = 0; 4680*37da2899SCharles.Forsyth } 4681*37da2899SCharles.Forsyth else 4682*37da2899SCharles.Forsyth { 4683*37da2899SCharles.Forsyth if ( CUR.opcode & 1 ) 4684*37da2899SCharles.Forsyth D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); 4685*37da2899SCharles.Forsyth else 4686*37da2899SCharles.Forsyth D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); 4687*37da2899SCharles.Forsyth } 4688*37da2899SCharles.Forsyth 4689*37da2899SCharles.Forsyth args[0] = D; 4690*37da2899SCharles.Forsyth } 4691*37da2899SCharles.Forsyth 4692*37da2899SCharles.Forsyth 4693*37da2899SCharles.Forsyth /*************************************************************************/ 4694*37da2899SCharles.Forsyth /* */ 4695*37da2899SCharles.Forsyth /* SDPVTL[a]: Set Dual PVector to Line */ 4696*37da2899SCharles.Forsyth /* Opcode range: 0x86-0x87 */ 4697*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 4698*37da2899SCharles.Forsyth /* */ 4699*37da2899SCharles.Forsyth static void Ins_SDPVTL(INS_ARG)4700*37da2899SCharles.Forsyth Ins_SDPVTL( INS_ARG ) 4701*37da2899SCharles.Forsyth { 4702*37da2899SCharles.Forsyth FT_Long A, B, C; 4703*37da2899SCharles.Forsyth FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ 4704*37da2899SCharles.Forsyth 4705*37da2899SCharles.Forsyth 4706*37da2899SCharles.Forsyth p1 = (FT_UShort)args[1]; 4707*37da2899SCharles.Forsyth p2 = (FT_UShort)args[0]; 4708*37da2899SCharles.Forsyth 4709*37da2899SCharles.Forsyth if ( BOUNDS( p2, CUR.zp1.n_points ) || 4710*37da2899SCharles.Forsyth BOUNDS( p1, CUR.zp2.n_points ) ) 4711*37da2899SCharles.Forsyth { 4712*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4713*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4714*37da2899SCharles.Forsyth return; 4715*37da2899SCharles.Forsyth } 4716*37da2899SCharles.Forsyth 4717*37da2899SCharles.Forsyth { 4718*37da2899SCharles.Forsyth FT_Vector* v1 = CUR.zp1.org + p2; 4719*37da2899SCharles.Forsyth FT_Vector* v2 = CUR.zp2.org + p1; 4720*37da2899SCharles.Forsyth 4721*37da2899SCharles.Forsyth 4722*37da2899SCharles.Forsyth A = v1->x - v2->x; 4723*37da2899SCharles.Forsyth B = v1->y - v2->y; 4724*37da2899SCharles.Forsyth } 4725*37da2899SCharles.Forsyth 4726*37da2899SCharles.Forsyth if ( ( CUR.opcode & 1 ) != 0 ) 4727*37da2899SCharles.Forsyth { 4728*37da2899SCharles.Forsyth C = B; /* counter clockwise rotation */ 4729*37da2899SCharles.Forsyth B = A; 4730*37da2899SCharles.Forsyth A = -C; 4731*37da2899SCharles.Forsyth } 4732*37da2899SCharles.Forsyth 4733*37da2899SCharles.Forsyth NORMalize( A, B, &CUR.GS.dualVector ); 4734*37da2899SCharles.Forsyth 4735*37da2899SCharles.Forsyth { 4736*37da2899SCharles.Forsyth FT_Vector* v1 = CUR.zp1.cur + p2; 4737*37da2899SCharles.Forsyth FT_Vector* v2 = CUR.zp2.cur + p1; 4738*37da2899SCharles.Forsyth 4739*37da2899SCharles.Forsyth 4740*37da2899SCharles.Forsyth A = v1->x - v2->x; 4741*37da2899SCharles.Forsyth B = v1->y - v2->y; 4742*37da2899SCharles.Forsyth } 4743*37da2899SCharles.Forsyth 4744*37da2899SCharles.Forsyth if ( ( CUR.opcode & 1 ) != 0 ) 4745*37da2899SCharles.Forsyth { 4746*37da2899SCharles.Forsyth C = B; /* counter clockwise rotation */ 4747*37da2899SCharles.Forsyth B = A; 4748*37da2899SCharles.Forsyth A = -C; 4749*37da2899SCharles.Forsyth } 4750*37da2899SCharles.Forsyth 4751*37da2899SCharles.Forsyth NORMalize( A, B, &CUR.GS.projVector ); 4752*37da2899SCharles.Forsyth 4753*37da2899SCharles.Forsyth COMPUTE_Funcs(); 4754*37da2899SCharles.Forsyth } 4755*37da2899SCharles.Forsyth 4756*37da2899SCharles.Forsyth 4757*37da2899SCharles.Forsyth /*************************************************************************/ 4758*37da2899SCharles.Forsyth /* */ 4759*37da2899SCharles.Forsyth /* SZP0[]: Set Zone Pointer 0 */ 4760*37da2899SCharles.Forsyth /* Opcode range: 0x13 */ 4761*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 4762*37da2899SCharles.Forsyth /* */ 4763*37da2899SCharles.Forsyth static void Ins_SZP0(INS_ARG)4764*37da2899SCharles.Forsyth Ins_SZP0( INS_ARG ) 4765*37da2899SCharles.Forsyth { 4766*37da2899SCharles.Forsyth switch ( (FT_Int)args[0] ) 4767*37da2899SCharles.Forsyth { 4768*37da2899SCharles.Forsyth case 0: 4769*37da2899SCharles.Forsyth CUR.zp0 = CUR.twilight; 4770*37da2899SCharles.Forsyth break; 4771*37da2899SCharles.Forsyth 4772*37da2899SCharles.Forsyth case 1: 4773*37da2899SCharles.Forsyth CUR.zp0 = CUR.pts; 4774*37da2899SCharles.Forsyth break; 4775*37da2899SCharles.Forsyth 4776*37da2899SCharles.Forsyth default: 4777*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4778*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4779*37da2899SCharles.Forsyth return; 4780*37da2899SCharles.Forsyth } 4781*37da2899SCharles.Forsyth 4782*37da2899SCharles.Forsyth CUR.GS.gep0 = (FT_UShort)args[0]; 4783*37da2899SCharles.Forsyth } 4784*37da2899SCharles.Forsyth 4785*37da2899SCharles.Forsyth 4786*37da2899SCharles.Forsyth /*************************************************************************/ 4787*37da2899SCharles.Forsyth /* */ 4788*37da2899SCharles.Forsyth /* SZP1[]: Set Zone Pointer 1 */ 4789*37da2899SCharles.Forsyth /* Opcode range: 0x14 */ 4790*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 4791*37da2899SCharles.Forsyth /* */ 4792*37da2899SCharles.Forsyth static void Ins_SZP1(INS_ARG)4793*37da2899SCharles.Forsyth Ins_SZP1( INS_ARG ) 4794*37da2899SCharles.Forsyth { 4795*37da2899SCharles.Forsyth switch ( (FT_Int)args[0] ) 4796*37da2899SCharles.Forsyth { 4797*37da2899SCharles.Forsyth case 0: 4798*37da2899SCharles.Forsyth CUR.zp1 = CUR.twilight; 4799*37da2899SCharles.Forsyth break; 4800*37da2899SCharles.Forsyth 4801*37da2899SCharles.Forsyth case 1: 4802*37da2899SCharles.Forsyth CUR.zp1 = CUR.pts; 4803*37da2899SCharles.Forsyth break; 4804*37da2899SCharles.Forsyth 4805*37da2899SCharles.Forsyth default: 4806*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4807*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4808*37da2899SCharles.Forsyth return; 4809*37da2899SCharles.Forsyth } 4810*37da2899SCharles.Forsyth 4811*37da2899SCharles.Forsyth CUR.GS.gep1 = (FT_UShort)args[0]; 4812*37da2899SCharles.Forsyth } 4813*37da2899SCharles.Forsyth 4814*37da2899SCharles.Forsyth 4815*37da2899SCharles.Forsyth /*************************************************************************/ 4816*37da2899SCharles.Forsyth /* */ 4817*37da2899SCharles.Forsyth /* SZP2[]: Set Zone Pointer 2 */ 4818*37da2899SCharles.Forsyth /* Opcode range: 0x15 */ 4819*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 4820*37da2899SCharles.Forsyth /* */ 4821*37da2899SCharles.Forsyth static void Ins_SZP2(INS_ARG)4822*37da2899SCharles.Forsyth Ins_SZP2( INS_ARG ) 4823*37da2899SCharles.Forsyth { 4824*37da2899SCharles.Forsyth switch ( (FT_Int)args[0] ) 4825*37da2899SCharles.Forsyth { 4826*37da2899SCharles.Forsyth case 0: 4827*37da2899SCharles.Forsyth CUR.zp2 = CUR.twilight; 4828*37da2899SCharles.Forsyth break; 4829*37da2899SCharles.Forsyth 4830*37da2899SCharles.Forsyth case 1: 4831*37da2899SCharles.Forsyth CUR.zp2 = CUR.pts; 4832*37da2899SCharles.Forsyth break; 4833*37da2899SCharles.Forsyth 4834*37da2899SCharles.Forsyth default: 4835*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4836*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4837*37da2899SCharles.Forsyth return; 4838*37da2899SCharles.Forsyth } 4839*37da2899SCharles.Forsyth 4840*37da2899SCharles.Forsyth CUR.GS.gep2 = (FT_UShort)args[0]; 4841*37da2899SCharles.Forsyth } 4842*37da2899SCharles.Forsyth 4843*37da2899SCharles.Forsyth 4844*37da2899SCharles.Forsyth /*************************************************************************/ 4845*37da2899SCharles.Forsyth /* */ 4846*37da2899SCharles.Forsyth /* SZPS[]: Set Zone PointerS */ 4847*37da2899SCharles.Forsyth /* Opcode range: 0x16 */ 4848*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 4849*37da2899SCharles.Forsyth /* */ 4850*37da2899SCharles.Forsyth static void Ins_SZPS(INS_ARG)4851*37da2899SCharles.Forsyth Ins_SZPS( INS_ARG ) 4852*37da2899SCharles.Forsyth { 4853*37da2899SCharles.Forsyth switch ( (FT_Int)args[0] ) 4854*37da2899SCharles.Forsyth { 4855*37da2899SCharles.Forsyth case 0: 4856*37da2899SCharles.Forsyth CUR.zp0 = CUR.twilight; 4857*37da2899SCharles.Forsyth break; 4858*37da2899SCharles.Forsyth 4859*37da2899SCharles.Forsyth case 1: 4860*37da2899SCharles.Forsyth CUR.zp0 = CUR.pts; 4861*37da2899SCharles.Forsyth break; 4862*37da2899SCharles.Forsyth 4863*37da2899SCharles.Forsyth default: 4864*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4865*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4866*37da2899SCharles.Forsyth return; 4867*37da2899SCharles.Forsyth } 4868*37da2899SCharles.Forsyth 4869*37da2899SCharles.Forsyth CUR.zp1 = CUR.zp0; 4870*37da2899SCharles.Forsyth CUR.zp2 = CUR.zp0; 4871*37da2899SCharles.Forsyth 4872*37da2899SCharles.Forsyth CUR.GS.gep0 = (FT_UShort)args[0]; 4873*37da2899SCharles.Forsyth CUR.GS.gep1 = (FT_UShort)args[0]; 4874*37da2899SCharles.Forsyth CUR.GS.gep2 = (FT_UShort)args[0]; 4875*37da2899SCharles.Forsyth } 4876*37da2899SCharles.Forsyth 4877*37da2899SCharles.Forsyth 4878*37da2899SCharles.Forsyth /*************************************************************************/ 4879*37da2899SCharles.Forsyth /* */ 4880*37da2899SCharles.Forsyth /* INSTCTRL[]: INSTruction ConTRoL */ 4881*37da2899SCharles.Forsyth /* Opcode range: 0x8e */ 4882*37da2899SCharles.Forsyth /* Stack: int32 int32 --> */ 4883*37da2899SCharles.Forsyth /* */ 4884*37da2899SCharles.Forsyth static void Ins_INSTCTRL(INS_ARG)4885*37da2899SCharles.Forsyth Ins_INSTCTRL( INS_ARG ) 4886*37da2899SCharles.Forsyth { 4887*37da2899SCharles.Forsyth FT_Long K, L; 4888*37da2899SCharles.Forsyth 4889*37da2899SCharles.Forsyth 4890*37da2899SCharles.Forsyth K = args[1]; 4891*37da2899SCharles.Forsyth L = args[0]; 4892*37da2899SCharles.Forsyth 4893*37da2899SCharles.Forsyth if ( K < 1 || K > 2 ) 4894*37da2899SCharles.Forsyth { 4895*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 4896*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 4897*37da2899SCharles.Forsyth return; 4898*37da2899SCharles.Forsyth } 4899*37da2899SCharles.Forsyth 4900*37da2899SCharles.Forsyth if ( L != 0 ) 4901*37da2899SCharles.Forsyth L = K; 4902*37da2899SCharles.Forsyth 4903*37da2899SCharles.Forsyth CUR.GS.instruct_control = FT_BOOL( 4904*37da2899SCharles.Forsyth ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); 4905*37da2899SCharles.Forsyth } 4906*37da2899SCharles.Forsyth 4907*37da2899SCharles.Forsyth 4908*37da2899SCharles.Forsyth /*************************************************************************/ 4909*37da2899SCharles.Forsyth /* */ 4910*37da2899SCharles.Forsyth /* SCANCTRL[]: SCAN ConTRoL */ 4911*37da2899SCharles.Forsyth /* Opcode range: 0x85 */ 4912*37da2899SCharles.Forsyth /* Stack: uint32? --> */ 4913*37da2899SCharles.Forsyth /* */ 4914*37da2899SCharles.Forsyth static void Ins_SCANCTRL(INS_ARG)4915*37da2899SCharles.Forsyth Ins_SCANCTRL( INS_ARG ) 4916*37da2899SCharles.Forsyth { 4917*37da2899SCharles.Forsyth FT_Int A; 4918*37da2899SCharles.Forsyth 4919*37da2899SCharles.Forsyth 4920*37da2899SCharles.Forsyth /* Get Threshold */ 4921*37da2899SCharles.Forsyth A = (FT_Int)( args[0] & 0xFF ); 4922*37da2899SCharles.Forsyth 4923*37da2899SCharles.Forsyth if ( A == 0xFF ) 4924*37da2899SCharles.Forsyth { 4925*37da2899SCharles.Forsyth CUR.GS.scan_control = TRUE; 4926*37da2899SCharles.Forsyth return; 4927*37da2899SCharles.Forsyth } 4928*37da2899SCharles.Forsyth else if ( A == 0 ) 4929*37da2899SCharles.Forsyth { 4930*37da2899SCharles.Forsyth CUR.GS.scan_control = FALSE; 4931*37da2899SCharles.Forsyth return; 4932*37da2899SCharles.Forsyth } 4933*37da2899SCharles.Forsyth 4934*37da2899SCharles.Forsyth A *= 64; 4935*37da2899SCharles.Forsyth 4936*37da2899SCharles.Forsyth #if 0 4937*37da2899SCharles.Forsyth if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) 4938*37da2899SCharles.Forsyth CUR.GS.scan_control = TRUE; 4939*37da2899SCharles.Forsyth #endif 4940*37da2899SCharles.Forsyth 4941*37da2899SCharles.Forsyth if ( (args[0] & 0x200) != 0 && CUR.tt_metrics.rotated ) 4942*37da2899SCharles.Forsyth CUR.GS.scan_control = TRUE; 4943*37da2899SCharles.Forsyth 4944*37da2899SCharles.Forsyth if ( (args[0] & 0x400) != 0 && CUR.tt_metrics.stretched ) 4945*37da2899SCharles.Forsyth CUR.GS.scan_control = TRUE; 4946*37da2899SCharles.Forsyth 4947*37da2899SCharles.Forsyth #if 0 4948*37da2899SCharles.Forsyth if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) 4949*37da2899SCharles.Forsyth CUR.GS.scan_control = FALSE; 4950*37da2899SCharles.Forsyth #endif 4951*37da2899SCharles.Forsyth 4952*37da2899SCharles.Forsyth if ( (args[0] & 0x1000) != 0 && CUR.tt_metrics.rotated ) 4953*37da2899SCharles.Forsyth CUR.GS.scan_control = FALSE; 4954*37da2899SCharles.Forsyth 4955*37da2899SCharles.Forsyth if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched ) 4956*37da2899SCharles.Forsyth CUR.GS.scan_control = FALSE; 4957*37da2899SCharles.Forsyth } 4958*37da2899SCharles.Forsyth 4959*37da2899SCharles.Forsyth 4960*37da2899SCharles.Forsyth /*************************************************************************/ 4961*37da2899SCharles.Forsyth /* */ 4962*37da2899SCharles.Forsyth /* SCANTYPE[]: SCAN TYPE */ 4963*37da2899SCharles.Forsyth /* Opcode range: 0x8D */ 4964*37da2899SCharles.Forsyth /* Stack: uint32? --> */ 4965*37da2899SCharles.Forsyth /* */ 4966*37da2899SCharles.Forsyth static void Ins_SCANTYPE(INS_ARG)4967*37da2899SCharles.Forsyth Ins_SCANTYPE( INS_ARG ) 4968*37da2899SCharles.Forsyth { 4969*37da2899SCharles.Forsyth /* for compatibility with future enhancements, */ 4970*37da2899SCharles.Forsyth /* we must ignore new modes */ 4971*37da2899SCharles.Forsyth 4972*37da2899SCharles.Forsyth if ( args[0] >= 0 && args[0] <= 5 ) 4973*37da2899SCharles.Forsyth { 4974*37da2899SCharles.Forsyth if ( args[0] == 3 ) 4975*37da2899SCharles.Forsyth args[0] = 2; 4976*37da2899SCharles.Forsyth 4977*37da2899SCharles.Forsyth CUR.GS.scan_type = (FT_Int)args[0]; 4978*37da2899SCharles.Forsyth } 4979*37da2899SCharles.Forsyth } 4980*37da2899SCharles.Forsyth 4981*37da2899SCharles.Forsyth 4982*37da2899SCharles.Forsyth /*************************************************************************/ 4983*37da2899SCharles.Forsyth /* */ 4984*37da2899SCharles.Forsyth /* MANAGING OUTLINES */ 4985*37da2899SCharles.Forsyth /* */ 4986*37da2899SCharles.Forsyth /* Instructions appear in the specification's order. */ 4987*37da2899SCharles.Forsyth /* */ 4988*37da2899SCharles.Forsyth /*************************************************************************/ 4989*37da2899SCharles.Forsyth 4990*37da2899SCharles.Forsyth 4991*37da2899SCharles.Forsyth /*************************************************************************/ 4992*37da2899SCharles.Forsyth /* */ 4993*37da2899SCharles.Forsyth /* FLIPPT[]: FLIP PoinT */ 4994*37da2899SCharles.Forsyth /* Opcode range: 0x80 */ 4995*37da2899SCharles.Forsyth /* Stack: uint32... --> */ 4996*37da2899SCharles.Forsyth /* */ 4997*37da2899SCharles.Forsyth static void Ins_FLIPPT(INS_ARG)4998*37da2899SCharles.Forsyth Ins_FLIPPT( INS_ARG ) 4999*37da2899SCharles.Forsyth { 5000*37da2899SCharles.Forsyth FT_UShort point; 5001*37da2899SCharles.Forsyth 5002*37da2899SCharles.Forsyth FT_UNUSED_ARG; 5003*37da2899SCharles.Forsyth 5004*37da2899SCharles.Forsyth 5005*37da2899SCharles.Forsyth if ( CUR.top < CUR.GS.loop ) 5006*37da2899SCharles.Forsyth { 5007*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Few_Arguments; 5008*37da2899SCharles.Forsyth return; 5009*37da2899SCharles.Forsyth } 5010*37da2899SCharles.Forsyth 5011*37da2899SCharles.Forsyth while ( CUR.GS.loop > 0 ) 5012*37da2899SCharles.Forsyth { 5013*37da2899SCharles.Forsyth CUR.args--; 5014*37da2899SCharles.Forsyth 5015*37da2899SCharles.Forsyth point = (FT_UShort)CUR.stack[CUR.args]; 5016*37da2899SCharles.Forsyth 5017*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.pts.n_points ) ) 5018*37da2899SCharles.Forsyth { 5019*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5020*37da2899SCharles.Forsyth { 5021*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5022*37da2899SCharles.Forsyth return; 5023*37da2899SCharles.Forsyth } 5024*37da2899SCharles.Forsyth } 5025*37da2899SCharles.Forsyth else 5026*37da2899SCharles.Forsyth CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; 5027*37da2899SCharles.Forsyth 5028*37da2899SCharles.Forsyth CUR.GS.loop--; 5029*37da2899SCharles.Forsyth } 5030*37da2899SCharles.Forsyth 5031*37da2899SCharles.Forsyth CUR.GS.loop = 1; 5032*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 5033*37da2899SCharles.Forsyth } 5034*37da2899SCharles.Forsyth 5035*37da2899SCharles.Forsyth 5036*37da2899SCharles.Forsyth /*************************************************************************/ 5037*37da2899SCharles.Forsyth /* */ 5038*37da2899SCharles.Forsyth /* FLIPRGON[]: FLIP RanGe ON */ 5039*37da2899SCharles.Forsyth /* Opcode range: 0x81 */ 5040*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 5041*37da2899SCharles.Forsyth /* */ 5042*37da2899SCharles.Forsyth static void Ins_FLIPRGON(INS_ARG)5043*37da2899SCharles.Forsyth Ins_FLIPRGON( INS_ARG ) 5044*37da2899SCharles.Forsyth { 5045*37da2899SCharles.Forsyth FT_UShort I, K, L; 5046*37da2899SCharles.Forsyth 5047*37da2899SCharles.Forsyth 5048*37da2899SCharles.Forsyth K = (FT_UShort)args[1]; 5049*37da2899SCharles.Forsyth L = (FT_UShort)args[0]; 5050*37da2899SCharles.Forsyth 5051*37da2899SCharles.Forsyth if ( BOUNDS( K, CUR.pts.n_points ) || 5052*37da2899SCharles.Forsyth BOUNDS( L, CUR.pts.n_points ) ) 5053*37da2899SCharles.Forsyth { 5054*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5055*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5056*37da2899SCharles.Forsyth return; 5057*37da2899SCharles.Forsyth } 5058*37da2899SCharles.Forsyth 5059*37da2899SCharles.Forsyth for ( I = L; I <= K; I++ ) 5060*37da2899SCharles.Forsyth CUR.pts.tags[I] |= FT_CURVE_TAG_ON; 5061*37da2899SCharles.Forsyth } 5062*37da2899SCharles.Forsyth 5063*37da2899SCharles.Forsyth 5064*37da2899SCharles.Forsyth /*************************************************************************/ 5065*37da2899SCharles.Forsyth /* */ 5066*37da2899SCharles.Forsyth /* FLIPRGOFF: FLIP RanGe OFF */ 5067*37da2899SCharles.Forsyth /* Opcode range: 0x82 */ 5068*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 5069*37da2899SCharles.Forsyth /* */ 5070*37da2899SCharles.Forsyth static void Ins_FLIPRGOFF(INS_ARG)5071*37da2899SCharles.Forsyth Ins_FLIPRGOFF( INS_ARG ) 5072*37da2899SCharles.Forsyth { 5073*37da2899SCharles.Forsyth FT_UShort I, K, L; 5074*37da2899SCharles.Forsyth 5075*37da2899SCharles.Forsyth 5076*37da2899SCharles.Forsyth K = (FT_UShort)args[1]; 5077*37da2899SCharles.Forsyth L = (FT_UShort)args[0]; 5078*37da2899SCharles.Forsyth 5079*37da2899SCharles.Forsyth if ( BOUNDS( K, CUR.pts.n_points ) || 5080*37da2899SCharles.Forsyth BOUNDS( L, CUR.pts.n_points ) ) 5081*37da2899SCharles.Forsyth { 5082*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5083*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5084*37da2899SCharles.Forsyth return; 5085*37da2899SCharles.Forsyth } 5086*37da2899SCharles.Forsyth 5087*37da2899SCharles.Forsyth for ( I = L; I <= K; I++ ) 5088*37da2899SCharles.Forsyth CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; 5089*37da2899SCharles.Forsyth } 5090*37da2899SCharles.Forsyth 5091*37da2899SCharles.Forsyth 5092*37da2899SCharles.Forsyth static FT_Bool Compute_Point_Displacement(EXEC_OP_ FT_F26Dot6 * x,FT_F26Dot6 * y,TT_GlyphZone zone,FT_UShort * refp)5093*37da2899SCharles.Forsyth Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, 5094*37da2899SCharles.Forsyth FT_F26Dot6* y, 5095*37da2899SCharles.Forsyth TT_GlyphZone zone, 5096*37da2899SCharles.Forsyth FT_UShort* refp ) 5097*37da2899SCharles.Forsyth { 5098*37da2899SCharles.Forsyth TT_GlyphZoneRec zp; 5099*37da2899SCharles.Forsyth FT_UShort p; 5100*37da2899SCharles.Forsyth FT_F26Dot6 d; 5101*37da2899SCharles.Forsyth 5102*37da2899SCharles.Forsyth 5103*37da2899SCharles.Forsyth if ( CUR.opcode & 1 ) 5104*37da2899SCharles.Forsyth { 5105*37da2899SCharles.Forsyth zp = CUR.zp0; 5106*37da2899SCharles.Forsyth p = CUR.GS.rp1; 5107*37da2899SCharles.Forsyth } 5108*37da2899SCharles.Forsyth else 5109*37da2899SCharles.Forsyth { 5110*37da2899SCharles.Forsyth zp = CUR.zp1; 5111*37da2899SCharles.Forsyth p = CUR.GS.rp2; 5112*37da2899SCharles.Forsyth } 5113*37da2899SCharles.Forsyth 5114*37da2899SCharles.Forsyth if ( BOUNDS( p, zp.n_points ) ) 5115*37da2899SCharles.Forsyth { 5116*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5117*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5118*37da2899SCharles.Forsyth return FAILURE; 5119*37da2899SCharles.Forsyth } 5120*37da2899SCharles.Forsyth 5121*37da2899SCharles.Forsyth *zone = zp; 5122*37da2899SCharles.Forsyth *refp = p; 5123*37da2899SCharles.Forsyth 5124*37da2899SCharles.Forsyth d = CUR_Func_project( zp.cur + p, zp.org + p ); 5125*37da2899SCharles.Forsyth 5126*37da2899SCharles.Forsyth #ifdef NO_APPLE_PATENT 5127*37da2899SCharles.Forsyth 5128*37da2899SCharles.Forsyth *x = TT_MulFix14( d, CUR.GS.freeVector.x ); 5129*37da2899SCharles.Forsyth *y = TT_MulFix14( d, CUR.GS.freeVector.y ); 5130*37da2899SCharles.Forsyth 5131*37da2899SCharles.Forsyth #else 5132*37da2899SCharles.Forsyth 5133*37da2899SCharles.Forsyth *x = TT_MULDIV( d, 5134*37da2899SCharles.Forsyth (FT_Long)CUR.GS.freeVector.x * 0x10000L, 5135*37da2899SCharles.Forsyth CUR.F_dot_P ); 5136*37da2899SCharles.Forsyth *y = TT_MULDIV( d, 5137*37da2899SCharles.Forsyth (FT_Long)CUR.GS.freeVector.y * 0x10000L, 5138*37da2899SCharles.Forsyth CUR.F_dot_P ); 5139*37da2899SCharles.Forsyth 5140*37da2899SCharles.Forsyth #endif /* NO_APPLE_PATENT */ 5141*37da2899SCharles.Forsyth 5142*37da2899SCharles.Forsyth return SUCCESS; 5143*37da2899SCharles.Forsyth } 5144*37da2899SCharles.Forsyth 5145*37da2899SCharles.Forsyth 5146*37da2899SCharles.Forsyth static void Move_Zp2_Point(EXEC_OP_ FT_UShort point,FT_F26Dot6 dx,FT_F26Dot6 dy,FT_Bool touch)5147*37da2899SCharles.Forsyth Move_Zp2_Point( EXEC_OP_ FT_UShort point, 5148*37da2899SCharles.Forsyth FT_F26Dot6 dx, 5149*37da2899SCharles.Forsyth FT_F26Dot6 dy, 5150*37da2899SCharles.Forsyth FT_Bool touch ) 5151*37da2899SCharles.Forsyth { 5152*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.x != 0 ) 5153*37da2899SCharles.Forsyth { 5154*37da2899SCharles.Forsyth CUR.zp2.cur[point].x += dx; 5155*37da2899SCharles.Forsyth if ( touch ) 5156*37da2899SCharles.Forsyth CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; 5157*37da2899SCharles.Forsyth } 5158*37da2899SCharles.Forsyth 5159*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.y != 0 ) 5160*37da2899SCharles.Forsyth { 5161*37da2899SCharles.Forsyth CUR.zp2.cur[point].y += dy; 5162*37da2899SCharles.Forsyth if ( touch ) 5163*37da2899SCharles.Forsyth CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; 5164*37da2899SCharles.Forsyth } 5165*37da2899SCharles.Forsyth } 5166*37da2899SCharles.Forsyth 5167*37da2899SCharles.Forsyth 5168*37da2899SCharles.Forsyth /*************************************************************************/ 5169*37da2899SCharles.Forsyth /* */ 5170*37da2899SCharles.Forsyth /* SHP[a]: SHift Point by the last point */ 5171*37da2899SCharles.Forsyth /* Opcode range: 0x32-0x33 */ 5172*37da2899SCharles.Forsyth /* Stack: uint32... --> */ 5173*37da2899SCharles.Forsyth /* */ 5174*37da2899SCharles.Forsyth static void Ins_SHP(INS_ARG)5175*37da2899SCharles.Forsyth Ins_SHP( INS_ARG ) 5176*37da2899SCharles.Forsyth { 5177*37da2899SCharles.Forsyth TT_GlyphZoneRec zp; 5178*37da2899SCharles.Forsyth FT_UShort refp; 5179*37da2899SCharles.Forsyth 5180*37da2899SCharles.Forsyth FT_F26Dot6 dx, 5181*37da2899SCharles.Forsyth dy; 5182*37da2899SCharles.Forsyth FT_UShort point; 5183*37da2899SCharles.Forsyth 5184*37da2899SCharles.Forsyth FT_UNUSED_ARG; 5185*37da2899SCharles.Forsyth 5186*37da2899SCharles.Forsyth 5187*37da2899SCharles.Forsyth if ( CUR.top < CUR.GS.loop ) 5188*37da2899SCharles.Forsyth { 5189*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5190*37da2899SCharles.Forsyth return; 5191*37da2899SCharles.Forsyth } 5192*37da2899SCharles.Forsyth 5193*37da2899SCharles.Forsyth if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5194*37da2899SCharles.Forsyth return; 5195*37da2899SCharles.Forsyth 5196*37da2899SCharles.Forsyth while ( CUR.GS.loop > 0 ) 5197*37da2899SCharles.Forsyth { 5198*37da2899SCharles.Forsyth CUR.args--; 5199*37da2899SCharles.Forsyth point = (FT_UShort)CUR.stack[CUR.args]; 5200*37da2899SCharles.Forsyth 5201*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp2.n_points ) ) 5202*37da2899SCharles.Forsyth { 5203*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5204*37da2899SCharles.Forsyth { 5205*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5206*37da2899SCharles.Forsyth return; 5207*37da2899SCharles.Forsyth } 5208*37da2899SCharles.Forsyth } 5209*37da2899SCharles.Forsyth else 5210*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! SHP touches the points */ 5211*37da2899SCharles.Forsyth MOVE_Zp2_Point( point, dx, dy, TRUE ); 5212*37da2899SCharles.Forsyth 5213*37da2899SCharles.Forsyth CUR.GS.loop--; 5214*37da2899SCharles.Forsyth } 5215*37da2899SCharles.Forsyth 5216*37da2899SCharles.Forsyth CUR.GS.loop = 1; 5217*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 5218*37da2899SCharles.Forsyth } 5219*37da2899SCharles.Forsyth 5220*37da2899SCharles.Forsyth 5221*37da2899SCharles.Forsyth /*************************************************************************/ 5222*37da2899SCharles.Forsyth /* */ 5223*37da2899SCharles.Forsyth /* SHC[a]: SHift Contour */ 5224*37da2899SCharles.Forsyth /* Opcode range: 0x34-35 */ 5225*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 5226*37da2899SCharles.Forsyth /* */ 5227*37da2899SCharles.Forsyth static void Ins_SHC(INS_ARG)5228*37da2899SCharles.Forsyth Ins_SHC( INS_ARG ) 5229*37da2899SCharles.Forsyth { 5230*37da2899SCharles.Forsyth TT_GlyphZoneRec zp; 5231*37da2899SCharles.Forsyth FT_UShort refp; 5232*37da2899SCharles.Forsyth FT_F26Dot6 dx, 5233*37da2899SCharles.Forsyth dy; 5234*37da2899SCharles.Forsyth 5235*37da2899SCharles.Forsyth FT_Short contour; 5236*37da2899SCharles.Forsyth FT_UShort first_point, last_point, i; 5237*37da2899SCharles.Forsyth 5238*37da2899SCharles.Forsyth 5239*37da2899SCharles.Forsyth contour = (FT_UShort)args[0]; 5240*37da2899SCharles.Forsyth 5241*37da2899SCharles.Forsyth if ( BOUNDS( contour, CUR.pts.n_contours ) ) 5242*37da2899SCharles.Forsyth { 5243*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5244*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5245*37da2899SCharles.Forsyth return; 5246*37da2899SCharles.Forsyth } 5247*37da2899SCharles.Forsyth 5248*37da2899SCharles.Forsyth if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5249*37da2899SCharles.Forsyth return; 5250*37da2899SCharles.Forsyth 5251*37da2899SCharles.Forsyth if ( contour == 0 ) 5252*37da2899SCharles.Forsyth first_point = 0; 5253*37da2899SCharles.Forsyth else 5254*37da2899SCharles.Forsyth first_point = (FT_UShort)(CUR.pts.contours[contour - 1] + 1); 5255*37da2899SCharles.Forsyth 5256*37da2899SCharles.Forsyth last_point = CUR.pts.contours[contour]; 5257*37da2899SCharles.Forsyth 5258*37da2899SCharles.Forsyth /* XXX: this is probably wrong... at least it prevents memory */ 5259*37da2899SCharles.Forsyth /* corruption when zp2 is the twilight zone */ 5260*37da2899SCharles.Forsyth if ( last_point > CUR.zp2.n_points ) 5261*37da2899SCharles.Forsyth { 5262*37da2899SCharles.Forsyth if ( CUR.zp2.n_points > 0 ) 5263*37da2899SCharles.Forsyth last_point = (FT_UShort)(CUR.zp2.n_points - 1); 5264*37da2899SCharles.Forsyth else 5265*37da2899SCharles.Forsyth last_point = 0; 5266*37da2899SCharles.Forsyth } 5267*37da2899SCharles.Forsyth 5268*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! SHC doesn't touch the points */ 5269*37da2899SCharles.Forsyth for ( i = first_point; i <= last_point; i++ ) 5270*37da2899SCharles.Forsyth { 5271*37da2899SCharles.Forsyth if ( zp.cur != CUR.zp2.cur || refp != i ) 5272*37da2899SCharles.Forsyth MOVE_Zp2_Point( i, dx, dy, FALSE ); 5273*37da2899SCharles.Forsyth } 5274*37da2899SCharles.Forsyth } 5275*37da2899SCharles.Forsyth 5276*37da2899SCharles.Forsyth 5277*37da2899SCharles.Forsyth /*************************************************************************/ 5278*37da2899SCharles.Forsyth /* */ 5279*37da2899SCharles.Forsyth /* SHZ[a]: SHift Zone */ 5280*37da2899SCharles.Forsyth /* Opcode range: 0x36-37 */ 5281*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 5282*37da2899SCharles.Forsyth /* */ 5283*37da2899SCharles.Forsyth static void Ins_SHZ(INS_ARG)5284*37da2899SCharles.Forsyth Ins_SHZ( INS_ARG ) 5285*37da2899SCharles.Forsyth { 5286*37da2899SCharles.Forsyth TT_GlyphZoneRec zp; 5287*37da2899SCharles.Forsyth FT_UShort refp; 5288*37da2899SCharles.Forsyth FT_F26Dot6 dx, 5289*37da2899SCharles.Forsyth dy; 5290*37da2899SCharles.Forsyth 5291*37da2899SCharles.Forsyth FT_UShort last_point, i; 5292*37da2899SCharles.Forsyth 5293*37da2899SCharles.Forsyth 5294*37da2899SCharles.Forsyth if ( BOUNDS( args[0], 2 ) ) 5295*37da2899SCharles.Forsyth { 5296*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5297*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5298*37da2899SCharles.Forsyth return; 5299*37da2899SCharles.Forsyth } 5300*37da2899SCharles.Forsyth 5301*37da2899SCharles.Forsyth if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5302*37da2899SCharles.Forsyth return; 5303*37da2899SCharles.Forsyth 5304*37da2899SCharles.Forsyth if ( CUR.zp2.n_points > 0 ) 5305*37da2899SCharles.Forsyth last_point = (FT_UShort)(CUR.zp2.n_points - 1); 5306*37da2899SCharles.Forsyth else 5307*37da2899SCharles.Forsyth last_point = 0; 5308*37da2899SCharles.Forsyth 5309*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ 5310*37da2899SCharles.Forsyth for ( i = 0; i <= last_point; i++ ) 5311*37da2899SCharles.Forsyth { 5312*37da2899SCharles.Forsyth if ( zp.cur != CUR.zp2.cur || refp != i ) 5313*37da2899SCharles.Forsyth MOVE_Zp2_Point( i, dx, dy, FALSE ); 5314*37da2899SCharles.Forsyth } 5315*37da2899SCharles.Forsyth } 5316*37da2899SCharles.Forsyth 5317*37da2899SCharles.Forsyth 5318*37da2899SCharles.Forsyth /*************************************************************************/ 5319*37da2899SCharles.Forsyth /* */ 5320*37da2899SCharles.Forsyth /* SHPIX[]: SHift points by a PIXel amount */ 5321*37da2899SCharles.Forsyth /* Opcode range: 0x38 */ 5322*37da2899SCharles.Forsyth /* Stack: f26.6 uint32... --> */ 5323*37da2899SCharles.Forsyth /* */ 5324*37da2899SCharles.Forsyth static void Ins_SHPIX(INS_ARG)5325*37da2899SCharles.Forsyth Ins_SHPIX( INS_ARG ) 5326*37da2899SCharles.Forsyth { 5327*37da2899SCharles.Forsyth FT_F26Dot6 dx, dy; 5328*37da2899SCharles.Forsyth FT_UShort point; 5329*37da2899SCharles.Forsyth 5330*37da2899SCharles.Forsyth 5331*37da2899SCharles.Forsyth if ( CUR.top < CUR.GS.loop + 1 ) 5332*37da2899SCharles.Forsyth { 5333*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5334*37da2899SCharles.Forsyth return; 5335*37da2899SCharles.Forsyth } 5336*37da2899SCharles.Forsyth 5337*37da2899SCharles.Forsyth dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); 5338*37da2899SCharles.Forsyth dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); 5339*37da2899SCharles.Forsyth 5340*37da2899SCharles.Forsyth while ( CUR.GS.loop > 0 ) 5341*37da2899SCharles.Forsyth { 5342*37da2899SCharles.Forsyth CUR.args--; 5343*37da2899SCharles.Forsyth 5344*37da2899SCharles.Forsyth point = (FT_UShort)CUR.stack[CUR.args]; 5345*37da2899SCharles.Forsyth 5346*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp2.n_points ) ) 5347*37da2899SCharles.Forsyth { 5348*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5349*37da2899SCharles.Forsyth { 5350*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5351*37da2899SCharles.Forsyth return; 5352*37da2899SCharles.Forsyth } 5353*37da2899SCharles.Forsyth } 5354*37da2899SCharles.Forsyth else 5355*37da2899SCharles.Forsyth MOVE_Zp2_Point( point, dx, dy, TRUE ); 5356*37da2899SCharles.Forsyth 5357*37da2899SCharles.Forsyth CUR.GS.loop--; 5358*37da2899SCharles.Forsyth } 5359*37da2899SCharles.Forsyth 5360*37da2899SCharles.Forsyth CUR.GS.loop = 1; 5361*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 5362*37da2899SCharles.Forsyth } 5363*37da2899SCharles.Forsyth 5364*37da2899SCharles.Forsyth 5365*37da2899SCharles.Forsyth /*************************************************************************/ 5366*37da2899SCharles.Forsyth /* */ 5367*37da2899SCharles.Forsyth /* MSIRP[a]: Move Stack Indirect Relative Position */ 5368*37da2899SCharles.Forsyth /* Opcode range: 0x3A-0x3B */ 5369*37da2899SCharles.Forsyth /* Stack: f26.6 uint32 --> */ 5370*37da2899SCharles.Forsyth /* */ 5371*37da2899SCharles.Forsyth static void Ins_MSIRP(INS_ARG)5372*37da2899SCharles.Forsyth Ins_MSIRP( INS_ARG ) 5373*37da2899SCharles.Forsyth { 5374*37da2899SCharles.Forsyth FT_UShort point; 5375*37da2899SCharles.Forsyth FT_F26Dot6 distance; 5376*37da2899SCharles.Forsyth 5377*37da2899SCharles.Forsyth 5378*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5379*37da2899SCharles.Forsyth 5380*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp1.n_points ) || 5381*37da2899SCharles.Forsyth BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 5382*37da2899SCharles.Forsyth { 5383*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5384*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5385*37da2899SCharles.Forsyth return; 5386*37da2899SCharles.Forsyth } 5387*37da2899SCharles.Forsyth 5388*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! behaviour */ 5389*37da2899SCharles.Forsyth if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ 5390*37da2899SCharles.Forsyth { 5391*37da2899SCharles.Forsyth CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; 5392*37da2899SCharles.Forsyth CUR.zp1.cur[point] = CUR.zp1.org[point]; 5393*37da2899SCharles.Forsyth } 5394*37da2899SCharles.Forsyth 5395*37da2899SCharles.Forsyth distance = CUR_Func_project( CUR.zp1.cur + point, 5396*37da2899SCharles.Forsyth CUR.zp0.cur + CUR.GS.rp0 ); 5397*37da2899SCharles.Forsyth 5398*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp1, point, args[1] - distance ); 5399*37da2899SCharles.Forsyth 5400*37da2899SCharles.Forsyth CUR.GS.rp1 = CUR.GS.rp0; 5401*37da2899SCharles.Forsyth CUR.GS.rp2 = point; 5402*37da2899SCharles.Forsyth 5403*37da2899SCharles.Forsyth if ( (CUR.opcode & 1) != 0 ) 5404*37da2899SCharles.Forsyth CUR.GS.rp0 = point; 5405*37da2899SCharles.Forsyth } 5406*37da2899SCharles.Forsyth 5407*37da2899SCharles.Forsyth 5408*37da2899SCharles.Forsyth /*************************************************************************/ 5409*37da2899SCharles.Forsyth /* */ 5410*37da2899SCharles.Forsyth /* MDAP[a]: Move Direct Absolute Point */ 5411*37da2899SCharles.Forsyth /* Opcode range: 0x2E-0x2F */ 5412*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 5413*37da2899SCharles.Forsyth /* */ 5414*37da2899SCharles.Forsyth static void Ins_MDAP(INS_ARG)5415*37da2899SCharles.Forsyth Ins_MDAP( INS_ARG ) 5416*37da2899SCharles.Forsyth { 5417*37da2899SCharles.Forsyth FT_UShort point; 5418*37da2899SCharles.Forsyth FT_F26Dot6 cur_dist, 5419*37da2899SCharles.Forsyth distance; 5420*37da2899SCharles.Forsyth 5421*37da2899SCharles.Forsyth 5422*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5423*37da2899SCharles.Forsyth 5424*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp0.n_points ) ) 5425*37da2899SCharles.Forsyth { 5426*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5427*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5428*37da2899SCharles.Forsyth return; 5429*37da2899SCharles.Forsyth } 5430*37da2899SCharles.Forsyth 5431*37da2899SCharles.Forsyth /* XXX: Is there some undocumented feature while in the */ 5432*37da2899SCharles.Forsyth /* twilight zone? ? */ 5433*37da2899SCharles.Forsyth if ( ( CUR.opcode & 1 ) != 0 ) 5434*37da2899SCharles.Forsyth { 5435*37da2899SCharles.Forsyth cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); 5436*37da2899SCharles.Forsyth distance = CUR_Func_round( cur_dist, 5437*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[0] ) - cur_dist; 5438*37da2899SCharles.Forsyth } 5439*37da2899SCharles.Forsyth else 5440*37da2899SCharles.Forsyth distance = 0; 5441*37da2899SCharles.Forsyth 5442*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp0, point, distance ); 5443*37da2899SCharles.Forsyth 5444*37da2899SCharles.Forsyth CUR.GS.rp0 = point; 5445*37da2899SCharles.Forsyth CUR.GS.rp1 = point; 5446*37da2899SCharles.Forsyth } 5447*37da2899SCharles.Forsyth 5448*37da2899SCharles.Forsyth 5449*37da2899SCharles.Forsyth /*************************************************************************/ 5450*37da2899SCharles.Forsyth /* */ 5451*37da2899SCharles.Forsyth /* MIAP[a]: Move Indirect Absolute Point */ 5452*37da2899SCharles.Forsyth /* Opcode range: 0x3E-0x3F */ 5453*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 5454*37da2899SCharles.Forsyth /* */ 5455*37da2899SCharles.Forsyth static void Ins_MIAP(INS_ARG)5456*37da2899SCharles.Forsyth Ins_MIAP( INS_ARG ) 5457*37da2899SCharles.Forsyth { 5458*37da2899SCharles.Forsyth FT_ULong cvtEntry; 5459*37da2899SCharles.Forsyth FT_UShort point; 5460*37da2899SCharles.Forsyth FT_F26Dot6 distance, 5461*37da2899SCharles.Forsyth org_dist; 5462*37da2899SCharles.Forsyth 5463*37da2899SCharles.Forsyth 5464*37da2899SCharles.Forsyth cvtEntry = (FT_ULong)args[1]; 5465*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5466*37da2899SCharles.Forsyth 5467*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp0.n_points ) || 5468*37da2899SCharles.Forsyth BOUNDS( cvtEntry, CUR.cvtSize ) ) 5469*37da2899SCharles.Forsyth { 5470*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5471*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5472*37da2899SCharles.Forsyth return; 5473*37da2899SCharles.Forsyth } 5474*37da2899SCharles.Forsyth 5475*37da2899SCharles.Forsyth /* UNDOCUMENTED! */ 5476*37da2899SCharles.Forsyth /* */ 5477*37da2899SCharles.Forsyth /* The behaviour of an MIAP instruction is quite */ 5478*37da2899SCharles.Forsyth /* different when used in the twilight zone. */ 5479*37da2899SCharles.Forsyth /* */ 5480*37da2899SCharles.Forsyth /* First, no control value cutin test is performed */ 5481*37da2899SCharles.Forsyth /* as it would fail anyway. Second, the original */ 5482*37da2899SCharles.Forsyth /* point, i.e. (org_x,org_y) of zp0.point, is set */ 5483*37da2899SCharles.Forsyth /* to the absolute, unrounded distance found in */ 5484*37da2899SCharles.Forsyth /* the CVT. */ 5485*37da2899SCharles.Forsyth /* */ 5486*37da2899SCharles.Forsyth /* This is used in the CVT programs of the Microsoft */ 5487*37da2899SCharles.Forsyth /* fonts Arial, Times, etc., in order to re-adjust */ 5488*37da2899SCharles.Forsyth /* some key font heights. It allows the use of the */ 5489*37da2899SCharles.Forsyth /* IP instruction in the twilight zone, which */ 5490*37da2899SCharles.Forsyth /* otherwise would be `illegal' according to the */ 5491*37da2899SCharles.Forsyth /* specification. */ 5492*37da2899SCharles.Forsyth /* */ 5493*37da2899SCharles.Forsyth /* We implement it with a special sequence for the */ 5494*37da2899SCharles.Forsyth /* twilight zone. This is a bad hack, but it seems */ 5495*37da2899SCharles.Forsyth /* to work. */ 5496*37da2899SCharles.Forsyth 5497*37da2899SCharles.Forsyth distance = CUR_Func_read_cvt( cvtEntry ); 5498*37da2899SCharles.Forsyth 5499*37da2899SCharles.Forsyth if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ 5500*37da2899SCharles.Forsyth { 5501*37da2899SCharles.Forsyth CUR.zp0.org[point].x = TT_MulFix14( distance, CUR.GS.freeVector.x ); 5502*37da2899SCharles.Forsyth CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ), 5503*37da2899SCharles.Forsyth CUR.zp0.cur[point] = CUR.zp0.org[point]; 5504*37da2899SCharles.Forsyth } 5505*37da2899SCharles.Forsyth 5506*37da2899SCharles.Forsyth org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); 5507*37da2899SCharles.Forsyth 5508*37da2899SCharles.Forsyth if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ 5509*37da2899SCharles.Forsyth { 5510*37da2899SCharles.Forsyth if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) 5511*37da2899SCharles.Forsyth distance = org_dist; 5512*37da2899SCharles.Forsyth 5513*37da2899SCharles.Forsyth distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); 5514*37da2899SCharles.Forsyth } 5515*37da2899SCharles.Forsyth 5516*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp0, point, distance - org_dist ); 5517*37da2899SCharles.Forsyth 5518*37da2899SCharles.Forsyth CUR.GS.rp0 = point; 5519*37da2899SCharles.Forsyth CUR.GS.rp1 = point; 5520*37da2899SCharles.Forsyth } 5521*37da2899SCharles.Forsyth 5522*37da2899SCharles.Forsyth 5523*37da2899SCharles.Forsyth /*************************************************************************/ 5524*37da2899SCharles.Forsyth /* */ 5525*37da2899SCharles.Forsyth /* MDRP[abcde]: Move Direct Relative Point */ 5526*37da2899SCharles.Forsyth /* Opcode range: 0xC0-0xDF */ 5527*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 5528*37da2899SCharles.Forsyth /* */ 5529*37da2899SCharles.Forsyth static void Ins_MDRP(INS_ARG)5530*37da2899SCharles.Forsyth Ins_MDRP( INS_ARG ) 5531*37da2899SCharles.Forsyth { 5532*37da2899SCharles.Forsyth FT_UShort point; 5533*37da2899SCharles.Forsyth FT_F26Dot6 org_dist, distance; 5534*37da2899SCharles.Forsyth 5535*37da2899SCharles.Forsyth 5536*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5537*37da2899SCharles.Forsyth 5538*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp1.n_points ) || 5539*37da2899SCharles.Forsyth BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 5540*37da2899SCharles.Forsyth { 5541*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5542*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5543*37da2899SCharles.Forsyth return; 5544*37da2899SCharles.Forsyth } 5545*37da2899SCharles.Forsyth 5546*37da2899SCharles.Forsyth /* XXX: Is there some undocumented feature while in the */ 5547*37da2899SCharles.Forsyth /* twilight zone? */ 5548*37da2899SCharles.Forsyth 5549*37da2899SCharles.Forsyth org_dist = CUR_Func_dualproj( CUR.zp1.org + point, 5550*37da2899SCharles.Forsyth CUR.zp0.org + CUR.GS.rp0 ); 5551*37da2899SCharles.Forsyth 5552*37da2899SCharles.Forsyth /* single width cutin test */ 5553*37da2899SCharles.Forsyth 5554*37da2899SCharles.Forsyth if ( ABS( org_dist ) < CUR.GS.single_width_cutin ) 5555*37da2899SCharles.Forsyth { 5556*37da2899SCharles.Forsyth if ( org_dist >= 0 ) 5557*37da2899SCharles.Forsyth org_dist = CUR.GS.single_width_value; 5558*37da2899SCharles.Forsyth else 5559*37da2899SCharles.Forsyth org_dist = -CUR.GS.single_width_value; 5560*37da2899SCharles.Forsyth } 5561*37da2899SCharles.Forsyth 5562*37da2899SCharles.Forsyth /* round flag */ 5563*37da2899SCharles.Forsyth 5564*37da2899SCharles.Forsyth if ( ( CUR.opcode & 4 ) != 0 ) 5565*37da2899SCharles.Forsyth distance = CUR_Func_round( 5566*37da2899SCharles.Forsyth org_dist, 5567*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode & 3] ); 5568*37da2899SCharles.Forsyth else 5569*37da2899SCharles.Forsyth distance = ROUND_None( 5570*37da2899SCharles.Forsyth org_dist, 5571*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode & 3] ); 5572*37da2899SCharles.Forsyth 5573*37da2899SCharles.Forsyth /* minimum distance flag */ 5574*37da2899SCharles.Forsyth 5575*37da2899SCharles.Forsyth if ( ( CUR.opcode & 8 ) != 0 ) 5576*37da2899SCharles.Forsyth { 5577*37da2899SCharles.Forsyth if ( org_dist >= 0 ) 5578*37da2899SCharles.Forsyth { 5579*37da2899SCharles.Forsyth if ( distance < CUR.GS.minimum_distance ) 5580*37da2899SCharles.Forsyth distance = CUR.GS.minimum_distance; 5581*37da2899SCharles.Forsyth } 5582*37da2899SCharles.Forsyth else 5583*37da2899SCharles.Forsyth { 5584*37da2899SCharles.Forsyth if ( distance > -CUR.GS.minimum_distance ) 5585*37da2899SCharles.Forsyth distance = -CUR.GS.minimum_distance; 5586*37da2899SCharles.Forsyth } 5587*37da2899SCharles.Forsyth } 5588*37da2899SCharles.Forsyth 5589*37da2899SCharles.Forsyth /* now move the point */ 5590*37da2899SCharles.Forsyth 5591*37da2899SCharles.Forsyth org_dist = CUR_Func_project( CUR.zp1.cur + point, 5592*37da2899SCharles.Forsyth CUR.zp0.cur + CUR.GS.rp0 ); 5593*37da2899SCharles.Forsyth 5594*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp1, point, distance - org_dist ); 5595*37da2899SCharles.Forsyth 5596*37da2899SCharles.Forsyth CUR.GS.rp1 = CUR.GS.rp0; 5597*37da2899SCharles.Forsyth CUR.GS.rp2 = point; 5598*37da2899SCharles.Forsyth 5599*37da2899SCharles.Forsyth if ( ( CUR.opcode & 16 ) != 0 ) 5600*37da2899SCharles.Forsyth CUR.GS.rp0 = point; 5601*37da2899SCharles.Forsyth } 5602*37da2899SCharles.Forsyth 5603*37da2899SCharles.Forsyth 5604*37da2899SCharles.Forsyth /*************************************************************************/ 5605*37da2899SCharles.Forsyth /* */ 5606*37da2899SCharles.Forsyth /* MIRP[abcde]: Move Indirect Relative Point */ 5607*37da2899SCharles.Forsyth /* Opcode range: 0xE0-0xFF */ 5608*37da2899SCharles.Forsyth /* Stack: int32? uint32 --> */ 5609*37da2899SCharles.Forsyth /* */ 5610*37da2899SCharles.Forsyth static void Ins_MIRP(INS_ARG)5611*37da2899SCharles.Forsyth Ins_MIRP( INS_ARG ) 5612*37da2899SCharles.Forsyth { 5613*37da2899SCharles.Forsyth FT_UShort point; 5614*37da2899SCharles.Forsyth FT_ULong cvtEntry; 5615*37da2899SCharles.Forsyth 5616*37da2899SCharles.Forsyth FT_F26Dot6 cvt_dist, 5617*37da2899SCharles.Forsyth distance, 5618*37da2899SCharles.Forsyth cur_dist, 5619*37da2899SCharles.Forsyth org_dist; 5620*37da2899SCharles.Forsyth 5621*37da2899SCharles.Forsyth 5622*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5623*37da2899SCharles.Forsyth cvtEntry = (FT_ULong)( args[1] + 1 ); 5624*37da2899SCharles.Forsyth 5625*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ 5626*37da2899SCharles.Forsyth 5627*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp1.n_points ) || 5628*37da2899SCharles.Forsyth BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || 5629*37da2899SCharles.Forsyth BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 5630*37da2899SCharles.Forsyth { 5631*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5632*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5633*37da2899SCharles.Forsyth return; 5634*37da2899SCharles.Forsyth } 5635*37da2899SCharles.Forsyth 5636*37da2899SCharles.Forsyth if ( !cvtEntry ) 5637*37da2899SCharles.Forsyth cvt_dist = 0; 5638*37da2899SCharles.Forsyth else 5639*37da2899SCharles.Forsyth cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); 5640*37da2899SCharles.Forsyth 5641*37da2899SCharles.Forsyth /* single width test */ 5642*37da2899SCharles.Forsyth 5643*37da2899SCharles.Forsyth if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin ) 5644*37da2899SCharles.Forsyth { 5645*37da2899SCharles.Forsyth if ( cvt_dist >= 0 ) 5646*37da2899SCharles.Forsyth cvt_dist = CUR.GS.single_width_value; 5647*37da2899SCharles.Forsyth else 5648*37da2899SCharles.Forsyth cvt_dist = -CUR.GS.single_width_value; 5649*37da2899SCharles.Forsyth } 5650*37da2899SCharles.Forsyth 5651*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! -- twilight zone */ 5652*37da2899SCharles.Forsyth 5653*37da2899SCharles.Forsyth if ( CUR.GS.gep1 == 0 ) 5654*37da2899SCharles.Forsyth { 5655*37da2899SCharles.Forsyth CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + 5656*37da2899SCharles.Forsyth TT_MulFix14( cvt_dist, CUR.GS.freeVector.x ); 5657*37da2899SCharles.Forsyth 5658*37da2899SCharles.Forsyth CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + 5659*37da2899SCharles.Forsyth TT_MulFix14( cvt_dist, CUR.GS.freeVector.y ); 5660*37da2899SCharles.Forsyth 5661*37da2899SCharles.Forsyth CUR.zp1.cur[point] = CUR.zp1.org[point]; 5662*37da2899SCharles.Forsyth } 5663*37da2899SCharles.Forsyth 5664*37da2899SCharles.Forsyth org_dist = CUR_Func_dualproj( CUR.zp1.org + point, 5665*37da2899SCharles.Forsyth CUR.zp0.org + CUR.GS.rp0 ); 5666*37da2899SCharles.Forsyth 5667*37da2899SCharles.Forsyth cur_dist = CUR_Func_project( CUR.zp1.cur + point, 5668*37da2899SCharles.Forsyth CUR.zp0.cur + CUR.GS.rp0 ); 5669*37da2899SCharles.Forsyth 5670*37da2899SCharles.Forsyth /* auto-flip test */ 5671*37da2899SCharles.Forsyth 5672*37da2899SCharles.Forsyth if ( CUR.GS.auto_flip ) 5673*37da2899SCharles.Forsyth { 5674*37da2899SCharles.Forsyth if ( ( org_dist ^ cvt_dist ) < 0 ) 5675*37da2899SCharles.Forsyth cvt_dist = -cvt_dist; 5676*37da2899SCharles.Forsyth } 5677*37da2899SCharles.Forsyth 5678*37da2899SCharles.Forsyth /* control value cutin and round */ 5679*37da2899SCharles.Forsyth 5680*37da2899SCharles.Forsyth if ( ( CUR.opcode & 4 ) != 0 ) 5681*37da2899SCharles.Forsyth { 5682*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ 5683*37da2899SCharles.Forsyth /* refer to the same zone. */ 5684*37da2899SCharles.Forsyth 5685*37da2899SCharles.Forsyth if ( CUR.GS.gep0 == CUR.GS.gep1 ) 5686*37da2899SCharles.Forsyth if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) 5687*37da2899SCharles.Forsyth cvt_dist = org_dist; 5688*37da2899SCharles.Forsyth 5689*37da2899SCharles.Forsyth distance = CUR_Func_round( 5690*37da2899SCharles.Forsyth cvt_dist, 5691*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode & 3] ); 5692*37da2899SCharles.Forsyth } 5693*37da2899SCharles.Forsyth else 5694*37da2899SCharles.Forsyth distance = ROUND_None( 5695*37da2899SCharles.Forsyth cvt_dist, 5696*37da2899SCharles.Forsyth CUR.tt_metrics.compensations[CUR.opcode & 3] ); 5697*37da2899SCharles.Forsyth 5698*37da2899SCharles.Forsyth /* minimum distance test */ 5699*37da2899SCharles.Forsyth 5700*37da2899SCharles.Forsyth if ( ( CUR.opcode & 8 ) != 0 ) 5701*37da2899SCharles.Forsyth { 5702*37da2899SCharles.Forsyth if ( org_dist >= 0 ) 5703*37da2899SCharles.Forsyth { 5704*37da2899SCharles.Forsyth if ( distance < CUR.GS.minimum_distance ) 5705*37da2899SCharles.Forsyth distance = CUR.GS.minimum_distance; 5706*37da2899SCharles.Forsyth } 5707*37da2899SCharles.Forsyth else 5708*37da2899SCharles.Forsyth { 5709*37da2899SCharles.Forsyth if ( distance > -CUR.GS.minimum_distance ) 5710*37da2899SCharles.Forsyth distance = -CUR.GS.minimum_distance; 5711*37da2899SCharles.Forsyth } 5712*37da2899SCharles.Forsyth } 5713*37da2899SCharles.Forsyth 5714*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); 5715*37da2899SCharles.Forsyth 5716*37da2899SCharles.Forsyth CUR.GS.rp1 = CUR.GS.rp0; 5717*37da2899SCharles.Forsyth 5718*37da2899SCharles.Forsyth if ( ( CUR.opcode & 16 ) != 0 ) 5719*37da2899SCharles.Forsyth CUR.GS.rp0 = point; 5720*37da2899SCharles.Forsyth 5721*37da2899SCharles.Forsyth /* XXX: UNDOCUMENTED! */ 5722*37da2899SCharles.Forsyth 5723*37da2899SCharles.Forsyth CUR.GS.rp2 = point; 5724*37da2899SCharles.Forsyth } 5725*37da2899SCharles.Forsyth 5726*37da2899SCharles.Forsyth 5727*37da2899SCharles.Forsyth /*************************************************************************/ 5728*37da2899SCharles.Forsyth /* */ 5729*37da2899SCharles.Forsyth /* ALIGNRP[]: ALIGN Relative Point */ 5730*37da2899SCharles.Forsyth /* Opcode range: 0x3C */ 5731*37da2899SCharles.Forsyth /* Stack: uint32 uint32... --> */ 5732*37da2899SCharles.Forsyth /* */ 5733*37da2899SCharles.Forsyth static void Ins_ALIGNRP(INS_ARG)5734*37da2899SCharles.Forsyth Ins_ALIGNRP( INS_ARG ) 5735*37da2899SCharles.Forsyth { 5736*37da2899SCharles.Forsyth FT_UShort point; 5737*37da2899SCharles.Forsyth FT_F26Dot6 distance; 5738*37da2899SCharles.Forsyth 5739*37da2899SCharles.Forsyth FT_UNUSED_ARG; 5740*37da2899SCharles.Forsyth 5741*37da2899SCharles.Forsyth 5742*37da2899SCharles.Forsyth if ( CUR.top < CUR.GS.loop || 5743*37da2899SCharles.Forsyth BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 5744*37da2899SCharles.Forsyth { 5745*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5746*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5747*37da2899SCharles.Forsyth return; 5748*37da2899SCharles.Forsyth } 5749*37da2899SCharles.Forsyth 5750*37da2899SCharles.Forsyth while ( CUR.GS.loop > 0 ) 5751*37da2899SCharles.Forsyth { 5752*37da2899SCharles.Forsyth CUR.args--; 5753*37da2899SCharles.Forsyth 5754*37da2899SCharles.Forsyth point = (FT_UShort)CUR.stack[CUR.args]; 5755*37da2899SCharles.Forsyth 5756*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp1.n_points ) ) 5757*37da2899SCharles.Forsyth { 5758*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5759*37da2899SCharles.Forsyth { 5760*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5761*37da2899SCharles.Forsyth return; 5762*37da2899SCharles.Forsyth } 5763*37da2899SCharles.Forsyth } 5764*37da2899SCharles.Forsyth else 5765*37da2899SCharles.Forsyth { 5766*37da2899SCharles.Forsyth distance = CUR_Func_project( CUR.zp1.cur + point, 5767*37da2899SCharles.Forsyth CUR.zp0.cur + CUR.GS.rp0 ); 5768*37da2899SCharles.Forsyth 5769*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp1, point, -distance ); 5770*37da2899SCharles.Forsyth } 5771*37da2899SCharles.Forsyth 5772*37da2899SCharles.Forsyth CUR.GS.loop--; 5773*37da2899SCharles.Forsyth } 5774*37da2899SCharles.Forsyth 5775*37da2899SCharles.Forsyth CUR.GS.loop = 1; 5776*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 5777*37da2899SCharles.Forsyth } 5778*37da2899SCharles.Forsyth 5779*37da2899SCharles.Forsyth 5780*37da2899SCharles.Forsyth /*************************************************************************/ 5781*37da2899SCharles.Forsyth /* */ 5782*37da2899SCharles.Forsyth /* ISECT[]: moves point to InterSECTion */ 5783*37da2899SCharles.Forsyth /* Opcode range: 0x0F */ 5784*37da2899SCharles.Forsyth /* Stack: 5 * uint32 --> */ 5785*37da2899SCharles.Forsyth /* */ 5786*37da2899SCharles.Forsyth static void Ins_ISECT(INS_ARG)5787*37da2899SCharles.Forsyth Ins_ISECT( INS_ARG ) 5788*37da2899SCharles.Forsyth { 5789*37da2899SCharles.Forsyth FT_UShort point, 5790*37da2899SCharles.Forsyth a0, a1, 5791*37da2899SCharles.Forsyth b0, b1; 5792*37da2899SCharles.Forsyth 5793*37da2899SCharles.Forsyth FT_F26Dot6 discriminant; 5794*37da2899SCharles.Forsyth 5795*37da2899SCharles.Forsyth FT_F26Dot6 dx, dy, 5796*37da2899SCharles.Forsyth dax, day, 5797*37da2899SCharles.Forsyth dbx, dby; 5798*37da2899SCharles.Forsyth 5799*37da2899SCharles.Forsyth FT_F26Dot6 val; 5800*37da2899SCharles.Forsyth 5801*37da2899SCharles.Forsyth FT_Vector R; 5802*37da2899SCharles.Forsyth 5803*37da2899SCharles.Forsyth 5804*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5805*37da2899SCharles.Forsyth 5806*37da2899SCharles.Forsyth a0 = (FT_UShort)args[1]; 5807*37da2899SCharles.Forsyth a1 = (FT_UShort)args[2]; 5808*37da2899SCharles.Forsyth b0 = (FT_UShort)args[3]; 5809*37da2899SCharles.Forsyth b1 = (FT_UShort)args[4]; 5810*37da2899SCharles.Forsyth 5811*37da2899SCharles.Forsyth if ( BOUNDS( b0, CUR.zp0.n_points ) || 5812*37da2899SCharles.Forsyth BOUNDS( b1, CUR.zp0.n_points ) || 5813*37da2899SCharles.Forsyth BOUNDS( a0, CUR.zp1.n_points ) || 5814*37da2899SCharles.Forsyth BOUNDS( a1, CUR.zp1.n_points ) || 5815*37da2899SCharles.Forsyth BOUNDS( point, CUR.zp2.n_points ) ) 5816*37da2899SCharles.Forsyth { 5817*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5818*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5819*37da2899SCharles.Forsyth return; 5820*37da2899SCharles.Forsyth } 5821*37da2899SCharles.Forsyth 5822*37da2899SCharles.Forsyth dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; 5823*37da2899SCharles.Forsyth dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; 5824*37da2899SCharles.Forsyth 5825*37da2899SCharles.Forsyth dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; 5826*37da2899SCharles.Forsyth day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; 5827*37da2899SCharles.Forsyth 5828*37da2899SCharles.Forsyth dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; 5829*37da2899SCharles.Forsyth dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; 5830*37da2899SCharles.Forsyth 5831*37da2899SCharles.Forsyth CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; 5832*37da2899SCharles.Forsyth 5833*37da2899SCharles.Forsyth discriminant = TT_MULDIV( dax, -dby, 0x40 ) + 5834*37da2899SCharles.Forsyth TT_MULDIV( day, dbx, 0x40 ); 5835*37da2899SCharles.Forsyth 5836*37da2899SCharles.Forsyth if ( ABS( discriminant ) >= 0x40 ) 5837*37da2899SCharles.Forsyth { 5838*37da2899SCharles.Forsyth val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); 5839*37da2899SCharles.Forsyth 5840*37da2899SCharles.Forsyth R.x = TT_MULDIV( val, dax, discriminant ); 5841*37da2899SCharles.Forsyth R.y = TT_MULDIV( val, day, discriminant ); 5842*37da2899SCharles.Forsyth 5843*37da2899SCharles.Forsyth CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; 5844*37da2899SCharles.Forsyth CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; 5845*37da2899SCharles.Forsyth } 5846*37da2899SCharles.Forsyth else 5847*37da2899SCharles.Forsyth { 5848*37da2899SCharles.Forsyth /* else, take the middle of the middles of A and B */ 5849*37da2899SCharles.Forsyth 5850*37da2899SCharles.Forsyth CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + 5851*37da2899SCharles.Forsyth CUR.zp1.cur[a1].x + 5852*37da2899SCharles.Forsyth CUR.zp0.cur[b0].x + 5853*37da2899SCharles.Forsyth CUR.zp0.cur[b1].x ) / 4; 5854*37da2899SCharles.Forsyth CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + 5855*37da2899SCharles.Forsyth CUR.zp1.cur[a1].y + 5856*37da2899SCharles.Forsyth CUR.zp0.cur[b0].y + 5857*37da2899SCharles.Forsyth CUR.zp0.cur[b1].y ) / 4; 5858*37da2899SCharles.Forsyth } 5859*37da2899SCharles.Forsyth } 5860*37da2899SCharles.Forsyth 5861*37da2899SCharles.Forsyth 5862*37da2899SCharles.Forsyth /*************************************************************************/ 5863*37da2899SCharles.Forsyth /* */ 5864*37da2899SCharles.Forsyth /* ALIGNPTS[]: ALIGN PoinTS */ 5865*37da2899SCharles.Forsyth /* Opcode range: 0x27 */ 5866*37da2899SCharles.Forsyth /* Stack: uint32 uint32 --> */ 5867*37da2899SCharles.Forsyth /* */ 5868*37da2899SCharles.Forsyth static void Ins_ALIGNPTS(INS_ARG)5869*37da2899SCharles.Forsyth Ins_ALIGNPTS( INS_ARG ) 5870*37da2899SCharles.Forsyth { 5871*37da2899SCharles.Forsyth FT_UShort p1, p2; 5872*37da2899SCharles.Forsyth FT_F26Dot6 distance; 5873*37da2899SCharles.Forsyth 5874*37da2899SCharles.Forsyth 5875*37da2899SCharles.Forsyth p1 = (FT_UShort)args[0]; 5876*37da2899SCharles.Forsyth p2 = (FT_UShort)args[1]; 5877*37da2899SCharles.Forsyth 5878*37da2899SCharles.Forsyth if ( BOUNDS( args[0], CUR.zp1.n_points ) || 5879*37da2899SCharles.Forsyth BOUNDS( args[1], CUR.zp0.n_points ) ) 5880*37da2899SCharles.Forsyth { 5881*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5882*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5883*37da2899SCharles.Forsyth return; 5884*37da2899SCharles.Forsyth } 5885*37da2899SCharles.Forsyth 5886*37da2899SCharles.Forsyth distance = CUR_Func_project( CUR.zp0.cur + p2, 5887*37da2899SCharles.Forsyth CUR.zp1.cur + p1 ) / 2; 5888*37da2899SCharles.Forsyth 5889*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp1, p1, distance ); 5890*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp0, p2, -distance ); 5891*37da2899SCharles.Forsyth } 5892*37da2899SCharles.Forsyth 5893*37da2899SCharles.Forsyth 5894*37da2899SCharles.Forsyth /*************************************************************************/ 5895*37da2899SCharles.Forsyth /* */ 5896*37da2899SCharles.Forsyth /* IP[]: Interpolate Point */ 5897*37da2899SCharles.Forsyth /* Opcode range: 0x39 */ 5898*37da2899SCharles.Forsyth /* Stack: uint32... --> */ 5899*37da2899SCharles.Forsyth /* */ 5900*37da2899SCharles.Forsyth static void Ins_IP(INS_ARG)5901*37da2899SCharles.Forsyth Ins_IP( INS_ARG ) 5902*37da2899SCharles.Forsyth { 5903*37da2899SCharles.Forsyth FT_F26Dot6 org_a, org_b, org_x, 5904*37da2899SCharles.Forsyth cur_a, cur_b, cur_x, 5905*37da2899SCharles.Forsyth distance; 5906*37da2899SCharles.Forsyth FT_UShort point; 5907*37da2899SCharles.Forsyth 5908*37da2899SCharles.Forsyth FT_UNUSED_ARG; 5909*37da2899SCharles.Forsyth 5910*37da2899SCharles.Forsyth 5911*37da2899SCharles.Forsyth if ( CUR.top < CUR.GS.loop ) 5912*37da2899SCharles.Forsyth { 5913*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5914*37da2899SCharles.Forsyth return; 5915*37da2899SCharles.Forsyth } 5916*37da2899SCharles.Forsyth 5917*37da2899SCharles.Forsyth /* XXX: There are some glyphs in some braindead but popular */ 5918*37da2899SCharles.Forsyth /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ 5919*37da2899SCharles.Forsyth /* calling IP[] with bad values of rp[12]. */ 5920*37da2899SCharles.Forsyth /* Do something sane when this odd thing happens. */ 5921*37da2899SCharles.Forsyth 5922*37da2899SCharles.Forsyth if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || 5923*37da2899SCharles.Forsyth BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) 5924*37da2899SCharles.Forsyth { 5925*37da2899SCharles.Forsyth org_a = cur_a = 0; 5926*37da2899SCharles.Forsyth org_b = cur_b = 0; 5927*37da2899SCharles.Forsyth } 5928*37da2899SCharles.Forsyth else 5929*37da2899SCharles.Forsyth { 5930*37da2899SCharles.Forsyth org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector ); 5931*37da2899SCharles.Forsyth org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector ); 5932*37da2899SCharles.Forsyth 5933*37da2899SCharles.Forsyth cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector ); 5934*37da2899SCharles.Forsyth cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector ); 5935*37da2899SCharles.Forsyth } 5936*37da2899SCharles.Forsyth 5937*37da2899SCharles.Forsyth while ( CUR.GS.loop > 0 ) 5938*37da2899SCharles.Forsyth { 5939*37da2899SCharles.Forsyth CUR.args--; 5940*37da2899SCharles.Forsyth 5941*37da2899SCharles.Forsyth point = (FT_UShort)CUR.stack[CUR.args]; 5942*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp2.n_points ) ) 5943*37da2899SCharles.Forsyth { 5944*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 5945*37da2899SCharles.Forsyth { 5946*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 5947*37da2899SCharles.Forsyth return; 5948*37da2899SCharles.Forsyth } 5949*37da2899SCharles.Forsyth } 5950*37da2899SCharles.Forsyth else 5951*37da2899SCharles.Forsyth { 5952*37da2899SCharles.Forsyth org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector ); 5953*37da2899SCharles.Forsyth cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector ); 5954*37da2899SCharles.Forsyth 5955*37da2899SCharles.Forsyth if ( ( org_a <= org_b && org_x <= org_a ) || 5956*37da2899SCharles.Forsyth ( org_a > org_b && org_x >= org_a ) ) 5957*37da2899SCharles.Forsyth 5958*37da2899SCharles.Forsyth distance = ( cur_a - org_a ) + ( org_x - cur_x ); 5959*37da2899SCharles.Forsyth 5960*37da2899SCharles.Forsyth else if ( ( org_a <= org_b && org_x >= org_b ) || 5961*37da2899SCharles.Forsyth ( org_a > org_b && org_x < org_b ) ) 5962*37da2899SCharles.Forsyth 5963*37da2899SCharles.Forsyth distance = ( cur_b - org_b ) + ( org_x - cur_x ); 5964*37da2899SCharles.Forsyth 5965*37da2899SCharles.Forsyth else 5966*37da2899SCharles.Forsyth /* note: it seems that rounding this value isn't a good */ 5967*37da2899SCharles.Forsyth /* idea (cf. width of capital `S' in Times) */ 5968*37da2899SCharles.Forsyth 5969*37da2899SCharles.Forsyth distance = TT_MULDIV( cur_b - cur_a, 5970*37da2899SCharles.Forsyth org_x - org_a, 5971*37da2899SCharles.Forsyth org_b - org_a ) + ( cur_a - cur_x ); 5972*37da2899SCharles.Forsyth 5973*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp2, point, distance ); 5974*37da2899SCharles.Forsyth } 5975*37da2899SCharles.Forsyth 5976*37da2899SCharles.Forsyth CUR.GS.loop--; 5977*37da2899SCharles.Forsyth } 5978*37da2899SCharles.Forsyth 5979*37da2899SCharles.Forsyth CUR.GS.loop = 1; 5980*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 5981*37da2899SCharles.Forsyth } 5982*37da2899SCharles.Forsyth 5983*37da2899SCharles.Forsyth 5984*37da2899SCharles.Forsyth /*************************************************************************/ 5985*37da2899SCharles.Forsyth /* */ 5986*37da2899SCharles.Forsyth /* UTP[a]: UnTouch Point */ 5987*37da2899SCharles.Forsyth /* Opcode range: 0x29 */ 5988*37da2899SCharles.Forsyth /* Stack: uint32 --> */ 5989*37da2899SCharles.Forsyth /* */ 5990*37da2899SCharles.Forsyth static void Ins_UTP(INS_ARG)5991*37da2899SCharles.Forsyth Ins_UTP( INS_ARG ) 5992*37da2899SCharles.Forsyth { 5993*37da2899SCharles.Forsyth FT_UShort point; 5994*37da2899SCharles.Forsyth FT_Byte mask; 5995*37da2899SCharles.Forsyth 5996*37da2899SCharles.Forsyth 5997*37da2899SCharles.Forsyth point = (FT_UShort)args[0]; 5998*37da2899SCharles.Forsyth 5999*37da2899SCharles.Forsyth if ( BOUNDS( point, CUR.zp0.n_points ) ) 6000*37da2899SCharles.Forsyth { 6001*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 6002*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 6003*37da2899SCharles.Forsyth return; 6004*37da2899SCharles.Forsyth } 6005*37da2899SCharles.Forsyth 6006*37da2899SCharles.Forsyth mask = 0xFF; 6007*37da2899SCharles.Forsyth 6008*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.x != 0 ) 6009*37da2899SCharles.Forsyth mask &= ~FT_CURVE_TAG_TOUCH_X; 6010*37da2899SCharles.Forsyth 6011*37da2899SCharles.Forsyth if ( CUR.GS.freeVector.y != 0 ) 6012*37da2899SCharles.Forsyth mask &= ~FT_CURVE_TAG_TOUCH_Y; 6013*37da2899SCharles.Forsyth 6014*37da2899SCharles.Forsyth CUR.zp0.tags[point] &= mask; 6015*37da2899SCharles.Forsyth } 6016*37da2899SCharles.Forsyth 6017*37da2899SCharles.Forsyth 6018*37da2899SCharles.Forsyth /* Local variables for Ins_IUP: */ 6019*37da2899SCharles.Forsyth struct LOC_Ins_IUP 6020*37da2899SCharles.Forsyth { 6021*37da2899SCharles.Forsyth FT_Vector* orgs; /* original and current coordinate */ 6022*37da2899SCharles.Forsyth FT_Vector* curs; /* arrays */ 6023*37da2899SCharles.Forsyth }; 6024*37da2899SCharles.Forsyth 6025*37da2899SCharles.Forsyth 6026*37da2899SCharles.Forsyth static void Shift(FT_UInt p1,FT_UInt p2,FT_UInt p,struct LOC_Ins_IUP * LINK)6027*37da2899SCharles.Forsyth Shift( FT_UInt p1, 6028*37da2899SCharles.Forsyth FT_UInt p2, 6029*37da2899SCharles.Forsyth FT_UInt p, 6030*37da2899SCharles.Forsyth struct LOC_Ins_IUP* LINK ) 6031*37da2899SCharles.Forsyth { 6032*37da2899SCharles.Forsyth FT_UInt i; 6033*37da2899SCharles.Forsyth FT_F26Dot6 x; 6034*37da2899SCharles.Forsyth 6035*37da2899SCharles.Forsyth 6036*37da2899SCharles.Forsyth x = LINK->curs[p].x - LINK->orgs[p].x; 6037*37da2899SCharles.Forsyth 6038*37da2899SCharles.Forsyth for ( i = p1; i < p; i++ ) 6039*37da2899SCharles.Forsyth LINK->curs[i].x += x; 6040*37da2899SCharles.Forsyth 6041*37da2899SCharles.Forsyth for ( i = p + 1; i <= p2; i++ ) 6042*37da2899SCharles.Forsyth LINK->curs[i].x += x; 6043*37da2899SCharles.Forsyth } 6044*37da2899SCharles.Forsyth 6045*37da2899SCharles.Forsyth 6046*37da2899SCharles.Forsyth static void Interp(FT_UInt p1,FT_UInt p2,FT_UInt ref1,FT_UInt ref2,struct LOC_Ins_IUP * LINK)6047*37da2899SCharles.Forsyth Interp( FT_UInt p1, 6048*37da2899SCharles.Forsyth FT_UInt p2, 6049*37da2899SCharles.Forsyth FT_UInt ref1, 6050*37da2899SCharles.Forsyth FT_UInt ref2, 6051*37da2899SCharles.Forsyth struct LOC_Ins_IUP* LINK ) 6052*37da2899SCharles.Forsyth { 6053*37da2899SCharles.Forsyth FT_UInt i; 6054*37da2899SCharles.Forsyth FT_F26Dot6 x, x1, x2, d1, d2; 6055*37da2899SCharles.Forsyth 6056*37da2899SCharles.Forsyth 6057*37da2899SCharles.Forsyth if ( p1 > p2 ) 6058*37da2899SCharles.Forsyth return; 6059*37da2899SCharles.Forsyth 6060*37da2899SCharles.Forsyth x1 = LINK->orgs[ref1].x; 6061*37da2899SCharles.Forsyth d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x; 6062*37da2899SCharles.Forsyth x2 = LINK->orgs[ref2].x; 6063*37da2899SCharles.Forsyth d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x; 6064*37da2899SCharles.Forsyth 6065*37da2899SCharles.Forsyth if ( x1 == x2 ) 6066*37da2899SCharles.Forsyth { 6067*37da2899SCharles.Forsyth for ( i = p1; i <= p2; i++ ) 6068*37da2899SCharles.Forsyth { 6069*37da2899SCharles.Forsyth x = LINK->orgs[i].x; 6070*37da2899SCharles.Forsyth 6071*37da2899SCharles.Forsyth if ( x <= x1 ) 6072*37da2899SCharles.Forsyth x += d1; 6073*37da2899SCharles.Forsyth else 6074*37da2899SCharles.Forsyth x += d2; 6075*37da2899SCharles.Forsyth 6076*37da2899SCharles.Forsyth LINK->curs[i].x = x; 6077*37da2899SCharles.Forsyth } 6078*37da2899SCharles.Forsyth return; 6079*37da2899SCharles.Forsyth } 6080*37da2899SCharles.Forsyth 6081*37da2899SCharles.Forsyth if ( x1 < x2 ) 6082*37da2899SCharles.Forsyth { 6083*37da2899SCharles.Forsyth for ( i = p1; i <= p2; i++ ) 6084*37da2899SCharles.Forsyth { 6085*37da2899SCharles.Forsyth x = LINK->orgs[i].x; 6086*37da2899SCharles.Forsyth 6087*37da2899SCharles.Forsyth if ( x <= x1 ) 6088*37da2899SCharles.Forsyth x += d1; 6089*37da2899SCharles.Forsyth else 6090*37da2899SCharles.Forsyth { 6091*37da2899SCharles.Forsyth if ( x >= x2 ) 6092*37da2899SCharles.Forsyth x += d2; 6093*37da2899SCharles.Forsyth else 6094*37da2899SCharles.Forsyth x = LINK->curs[ref1].x + 6095*37da2899SCharles.Forsyth TT_MULDIV( x - x1, 6096*37da2899SCharles.Forsyth LINK->curs[ref2].x - LINK->curs[ref1].x, 6097*37da2899SCharles.Forsyth x2 - x1 ); 6098*37da2899SCharles.Forsyth } 6099*37da2899SCharles.Forsyth LINK->curs[i].x = x; 6100*37da2899SCharles.Forsyth } 6101*37da2899SCharles.Forsyth return; 6102*37da2899SCharles.Forsyth } 6103*37da2899SCharles.Forsyth 6104*37da2899SCharles.Forsyth /* x2 < x1 */ 6105*37da2899SCharles.Forsyth 6106*37da2899SCharles.Forsyth for ( i = p1; i <= p2; i++ ) 6107*37da2899SCharles.Forsyth { 6108*37da2899SCharles.Forsyth x = LINK->orgs[i].x; 6109*37da2899SCharles.Forsyth if ( x <= x2 ) 6110*37da2899SCharles.Forsyth x += d2; 6111*37da2899SCharles.Forsyth else 6112*37da2899SCharles.Forsyth { 6113*37da2899SCharles.Forsyth if ( x >= x1 ) 6114*37da2899SCharles.Forsyth x += d1; 6115*37da2899SCharles.Forsyth else 6116*37da2899SCharles.Forsyth x = LINK->curs[ref1].x + 6117*37da2899SCharles.Forsyth TT_MULDIV( x - x1, 6118*37da2899SCharles.Forsyth LINK->curs[ref2].x - LINK->curs[ref1].x, 6119*37da2899SCharles.Forsyth x2 - x1 ); 6120*37da2899SCharles.Forsyth } 6121*37da2899SCharles.Forsyth LINK->curs[i].x = x; 6122*37da2899SCharles.Forsyth } 6123*37da2899SCharles.Forsyth } 6124*37da2899SCharles.Forsyth 6125*37da2899SCharles.Forsyth 6126*37da2899SCharles.Forsyth /*************************************************************************/ 6127*37da2899SCharles.Forsyth /* */ 6128*37da2899SCharles.Forsyth /* IUP[a]: Interpolate Untouched Points */ 6129*37da2899SCharles.Forsyth /* Opcode range: 0x30-0x31 */ 6130*37da2899SCharles.Forsyth /* Stack: --> */ 6131*37da2899SCharles.Forsyth /* */ 6132*37da2899SCharles.Forsyth static void Ins_IUP(INS_ARG)6133*37da2899SCharles.Forsyth Ins_IUP( INS_ARG ) 6134*37da2899SCharles.Forsyth { 6135*37da2899SCharles.Forsyth struct LOC_Ins_IUP V; 6136*37da2899SCharles.Forsyth FT_Byte mask; 6137*37da2899SCharles.Forsyth 6138*37da2899SCharles.Forsyth FT_UInt first_point; /* first point of contour */ 6139*37da2899SCharles.Forsyth FT_UInt end_point; /* end point (last+1) of contour */ 6140*37da2899SCharles.Forsyth 6141*37da2899SCharles.Forsyth FT_UInt first_touched; /* first touched point in contour */ 6142*37da2899SCharles.Forsyth FT_UInt cur_touched; /* current touched point in contour */ 6143*37da2899SCharles.Forsyth 6144*37da2899SCharles.Forsyth FT_UInt point; /* current point */ 6145*37da2899SCharles.Forsyth FT_Short contour; /* current contour */ 6146*37da2899SCharles.Forsyth 6147*37da2899SCharles.Forsyth FT_UNUSED_ARG; 6148*37da2899SCharles.Forsyth 6149*37da2899SCharles.Forsyth 6150*37da2899SCharles.Forsyth if ( CUR.opcode & 1 ) 6151*37da2899SCharles.Forsyth { 6152*37da2899SCharles.Forsyth mask = FT_CURVE_TAG_TOUCH_X; 6153*37da2899SCharles.Forsyth V.orgs = CUR.pts.org; 6154*37da2899SCharles.Forsyth V.curs = CUR.pts.cur; 6155*37da2899SCharles.Forsyth } 6156*37da2899SCharles.Forsyth else 6157*37da2899SCharles.Forsyth { 6158*37da2899SCharles.Forsyth mask = FT_CURVE_TAG_TOUCH_Y; 6159*37da2899SCharles.Forsyth V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); 6160*37da2899SCharles.Forsyth V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); 6161*37da2899SCharles.Forsyth } 6162*37da2899SCharles.Forsyth 6163*37da2899SCharles.Forsyth contour = 0; 6164*37da2899SCharles.Forsyth point = 0; 6165*37da2899SCharles.Forsyth 6166*37da2899SCharles.Forsyth do 6167*37da2899SCharles.Forsyth { 6168*37da2899SCharles.Forsyth end_point = CUR.pts.contours[contour]; 6169*37da2899SCharles.Forsyth first_point = point; 6170*37da2899SCharles.Forsyth 6171*37da2899SCharles.Forsyth while ( point <= end_point && (CUR.pts.tags[point] & mask) == 0 ) 6172*37da2899SCharles.Forsyth point++; 6173*37da2899SCharles.Forsyth 6174*37da2899SCharles.Forsyth if ( point <= end_point ) 6175*37da2899SCharles.Forsyth { 6176*37da2899SCharles.Forsyth first_touched = point; 6177*37da2899SCharles.Forsyth cur_touched = point; 6178*37da2899SCharles.Forsyth 6179*37da2899SCharles.Forsyth point++; 6180*37da2899SCharles.Forsyth 6181*37da2899SCharles.Forsyth while ( point <= end_point ) 6182*37da2899SCharles.Forsyth { 6183*37da2899SCharles.Forsyth if ( ( CUR.pts.tags[point] & mask ) != 0 ) 6184*37da2899SCharles.Forsyth { 6185*37da2899SCharles.Forsyth if ( point > 0 ) 6186*37da2899SCharles.Forsyth Interp( cur_touched + 1, 6187*37da2899SCharles.Forsyth point - 1, 6188*37da2899SCharles.Forsyth cur_touched, 6189*37da2899SCharles.Forsyth point, 6190*37da2899SCharles.Forsyth &V ); 6191*37da2899SCharles.Forsyth cur_touched = point; 6192*37da2899SCharles.Forsyth } 6193*37da2899SCharles.Forsyth 6194*37da2899SCharles.Forsyth point++; 6195*37da2899SCharles.Forsyth } 6196*37da2899SCharles.Forsyth 6197*37da2899SCharles.Forsyth if ( cur_touched == first_touched ) 6198*37da2899SCharles.Forsyth Shift( first_point, end_point, cur_touched, &V ); 6199*37da2899SCharles.Forsyth else 6200*37da2899SCharles.Forsyth { 6201*37da2899SCharles.Forsyth Interp( (FT_UShort)( cur_touched + 1 ), 6202*37da2899SCharles.Forsyth end_point, 6203*37da2899SCharles.Forsyth cur_touched, 6204*37da2899SCharles.Forsyth first_touched, 6205*37da2899SCharles.Forsyth &V ); 6206*37da2899SCharles.Forsyth 6207*37da2899SCharles.Forsyth if ( first_touched > 0 ) 6208*37da2899SCharles.Forsyth Interp( first_point, 6209*37da2899SCharles.Forsyth first_touched - 1, 6210*37da2899SCharles.Forsyth cur_touched, 6211*37da2899SCharles.Forsyth first_touched, 6212*37da2899SCharles.Forsyth &V ); 6213*37da2899SCharles.Forsyth } 6214*37da2899SCharles.Forsyth } 6215*37da2899SCharles.Forsyth contour++; 6216*37da2899SCharles.Forsyth } while ( contour < CUR.pts.n_contours ); 6217*37da2899SCharles.Forsyth } 6218*37da2899SCharles.Forsyth 6219*37da2899SCharles.Forsyth 6220*37da2899SCharles.Forsyth /*************************************************************************/ 6221*37da2899SCharles.Forsyth /* */ 6222*37da2899SCharles.Forsyth /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ 6223*37da2899SCharles.Forsyth /* Opcode range: 0x5D,0x71,0x72 */ 6224*37da2899SCharles.Forsyth /* Stack: uint32 (2 * uint32)... --> */ 6225*37da2899SCharles.Forsyth /* */ 6226*37da2899SCharles.Forsyth static void Ins_DELTAP(INS_ARG)6227*37da2899SCharles.Forsyth Ins_DELTAP( INS_ARG ) 6228*37da2899SCharles.Forsyth { 6229*37da2899SCharles.Forsyth FT_ULong k, nump; 6230*37da2899SCharles.Forsyth FT_UShort A; 6231*37da2899SCharles.Forsyth FT_ULong C; 6232*37da2899SCharles.Forsyth FT_Long B; 6233*37da2899SCharles.Forsyth 6234*37da2899SCharles.Forsyth 6235*37da2899SCharles.Forsyth nump = (FT_ULong)args[0]; /* some points theoretically may occur more 6236*37da2899SCharles.Forsyth than once, thus UShort isn't enough */ 6237*37da2899SCharles.Forsyth 6238*37da2899SCharles.Forsyth for ( k = 1; k <= nump; k++ ) 6239*37da2899SCharles.Forsyth { 6240*37da2899SCharles.Forsyth if ( CUR.args < 2 ) 6241*37da2899SCharles.Forsyth { 6242*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Few_Arguments; 6243*37da2899SCharles.Forsyth return; 6244*37da2899SCharles.Forsyth } 6245*37da2899SCharles.Forsyth 6246*37da2899SCharles.Forsyth CUR.args -= 2; 6247*37da2899SCharles.Forsyth 6248*37da2899SCharles.Forsyth A = (FT_UShort)CUR.stack[CUR.args + 1]; 6249*37da2899SCharles.Forsyth B = CUR.stack[CUR.args]; 6250*37da2899SCharles.Forsyth 6251*37da2899SCharles.Forsyth /* XXX: Because some popular fonts contain some invalid DeltaP */ 6252*37da2899SCharles.Forsyth /* instructions, we simply ignore them when the stacked */ 6253*37da2899SCharles.Forsyth /* point reference is off limit, rather than returning an */ 6254*37da2899SCharles.Forsyth /* error. As a delta instruction doesn't change a glyph */ 6255*37da2899SCharles.Forsyth /* in great ways, this shouldn't be a problem. */ 6256*37da2899SCharles.Forsyth 6257*37da2899SCharles.Forsyth if ( !BOUNDS( A, CUR.zp0.n_points ) ) 6258*37da2899SCharles.Forsyth { 6259*37da2899SCharles.Forsyth C = ( (FT_ULong)B & 0xF0 ) >> 4; 6260*37da2899SCharles.Forsyth 6261*37da2899SCharles.Forsyth switch ( CUR.opcode ) 6262*37da2899SCharles.Forsyth { 6263*37da2899SCharles.Forsyth case 0x5D: 6264*37da2899SCharles.Forsyth break; 6265*37da2899SCharles.Forsyth 6266*37da2899SCharles.Forsyth case 0x71: 6267*37da2899SCharles.Forsyth C += 16; 6268*37da2899SCharles.Forsyth break; 6269*37da2899SCharles.Forsyth 6270*37da2899SCharles.Forsyth case 0x72: 6271*37da2899SCharles.Forsyth C += 32; 6272*37da2899SCharles.Forsyth break; 6273*37da2899SCharles.Forsyth } 6274*37da2899SCharles.Forsyth 6275*37da2899SCharles.Forsyth C += CUR.GS.delta_base; 6276*37da2899SCharles.Forsyth 6277*37da2899SCharles.Forsyth if ( CURRENT_Ppem() == (FT_Long)C ) 6278*37da2899SCharles.Forsyth { 6279*37da2899SCharles.Forsyth B = ( (FT_ULong)B & 0xF ) - 8; 6280*37da2899SCharles.Forsyth if ( B >= 0 ) 6281*37da2899SCharles.Forsyth B++; 6282*37da2899SCharles.Forsyth B = B * 64 / ( 1L << CUR.GS.delta_shift ); 6283*37da2899SCharles.Forsyth 6284*37da2899SCharles.Forsyth CUR_Func_move( &CUR.zp0, A, B ); 6285*37da2899SCharles.Forsyth } 6286*37da2899SCharles.Forsyth } 6287*37da2899SCharles.Forsyth else 6288*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 6289*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 6290*37da2899SCharles.Forsyth } 6291*37da2899SCharles.Forsyth 6292*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 6293*37da2899SCharles.Forsyth } 6294*37da2899SCharles.Forsyth 6295*37da2899SCharles.Forsyth 6296*37da2899SCharles.Forsyth /*************************************************************************/ 6297*37da2899SCharles.Forsyth /* */ 6298*37da2899SCharles.Forsyth /* DELTACn[]: DELTA exceptions C1, C2, C3 */ 6299*37da2899SCharles.Forsyth /* Opcode range: 0x73,0x74,0x75 */ 6300*37da2899SCharles.Forsyth /* Stack: uint32 (2 * uint32)... --> */ 6301*37da2899SCharles.Forsyth /* */ 6302*37da2899SCharles.Forsyth static void Ins_DELTAC(INS_ARG)6303*37da2899SCharles.Forsyth Ins_DELTAC( INS_ARG ) 6304*37da2899SCharles.Forsyth { 6305*37da2899SCharles.Forsyth FT_ULong nump, k; 6306*37da2899SCharles.Forsyth FT_ULong A, C; 6307*37da2899SCharles.Forsyth FT_Long B; 6308*37da2899SCharles.Forsyth 6309*37da2899SCharles.Forsyth 6310*37da2899SCharles.Forsyth nump = (FT_ULong)args[0]; 6311*37da2899SCharles.Forsyth 6312*37da2899SCharles.Forsyth for ( k = 1; k <= nump; k++ ) 6313*37da2899SCharles.Forsyth { 6314*37da2899SCharles.Forsyth if ( CUR.args < 2 ) 6315*37da2899SCharles.Forsyth { 6316*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Few_Arguments; 6317*37da2899SCharles.Forsyth return; 6318*37da2899SCharles.Forsyth } 6319*37da2899SCharles.Forsyth 6320*37da2899SCharles.Forsyth CUR.args -= 2; 6321*37da2899SCharles.Forsyth 6322*37da2899SCharles.Forsyth A = (FT_ULong)CUR.stack[CUR.args + 1]; 6323*37da2899SCharles.Forsyth B = CUR.stack[CUR.args]; 6324*37da2899SCharles.Forsyth 6325*37da2899SCharles.Forsyth if ( BOUNDS( A, CUR.cvtSize ) ) 6326*37da2899SCharles.Forsyth { 6327*37da2899SCharles.Forsyth if ( CUR.pedantic_hinting ) 6328*37da2899SCharles.Forsyth { 6329*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 6330*37da2899SCharles.Forsyth return; 6331*37da2899SCharles.Forsyth } 6332*37da2899SCharles.Forsyth } 6333*37da2899SCharles.Forsyth else 6334*37da2899SCharles.Forsyth { 6335*37da2899SCharles.Forsyth C = ( (FT_ULong)B & 0xF0 ) >> 4; 6336*37da2899SCharles.Forsyth 6337*37da2899SCharles.Forsyth switch ( CUR.opcode ) 6338*37da2899SCharles.Forsyth { 6339*37da2899SCharles.Forsyth case 0x73: 6340*37da2899SCharles.Forsyth break; 6341*37da2899SCharles.Forsyth 6342*37da2899SCharles.Forsyth case 0x74: 6343*37da2899SCharles.Forsyth C += 16; 6344*37da2899SCharles.Forsyth break; 6345*37da2899SCharles.Forsyth 6346*37da2899SCharles.Forsyth case 0x75: 6347*37da2899SCharles.Forsyth C += 32; 6348*37da2899SCharles.Forsyth break; 6349*37da2899SCharles.Forsyth } 6350*37da2899SCharles.Forsyth 6351*37da2899SCharles.Forsyth C += CUR.GS.delta_base; 6352*37da2899SCharles.Forsyth 6353*37da2899SCharles.Forsyth if ( CURRENT_Ppem() == (FT_Long)C ) 6354*37da2899SCharles.Forsyth { 6355*37da2899SCharles.Forsyth B = ( (FT_ULong)B & 0xF ) - 8; 6356*37da2899SCharles.Forsyth if ( B >= 0 ) 6357*37da2899SCharles.Forsyth B++; 6358*37da2899SCharles.Forsyth B = B * 64 / ( 1L << CUR.GS.delta_shift ); 6359*37da2899SCharles.Forsyth 6360*37da2899SCharles.Forsyth CUR_Func_move_cvt( A, B ); 6361*37da2899SCharles.Forsyth } 6362*37da2899SCharles.Forsyth } 6363*37da2899SCharles.Forsyth } 6364*37da2899SCharles.Forsyth 6365*37da2899SCharles.Forsyth CUR.new_top = CUR.args; 6366*37da2899SCharles.Forsyth } 6367*37da2899SCharles.Forsyth 6368*37da2899SCharles.Forsyth 6369*37da2899SCharles.Forsyth /*************************************************************************/ 6370*37da2899SCharles.Forsyth /* */ 6371*37da2899SCharles.Forsyth /* MISC. INSTRUCTIONS */ 6372*37da2899SCharles.Forsyth /* */ 6373*37da2899SCharles.Forsyth /*************************************************************************/ 6374*37da2899SCharles.Forsyth 6375*37da2899SCharles.Forsyth 6376*37da2899SCharles.Forsyth /*************************************************************************/ 6377*37da2899SCharles.Forsyth /* */ 6378*37da2899SCharles.Forsyth /* GETINFO[]: GET INFOrmation */ 6379*37da2899SCharles.Forsyth /* Opcode range: 0x88 */ 6380*37da2899SCharles.Forsyth /* Stack: uint32 --> uint32 */ 6381*37da2899SCharles.Forsyth /* */ 6382*37da2899SCharles.Forsyth /* XXX: According to Apple specs, bits 1 & 2 of the argument ought to be */ 6383*37da2899SCharles.Forsyth /* consulted before rotated/stretched info is returned. */ 6384*37da2899SCharles.Forsyth static void Ins_GETINFO(INS_ARG)6385*37da2899SCharles.Forsyth Ins_GETINFO( INS_ARG ) 6386*37da2899SCharles.Forsyth { 6387*37da2899SCharles.Forsyth FT_Long K; 6388*37da2899SCharles.Forsyth 6389*37da2899SCharles.Forsyth 6390*37da2899SCharles.Forsyth K = 0; 6391*37da2899SCharles.Forsyth 6392*37da2899SCharles.Forsyth /* We return then Windows 3.1 version number */ 6393*37da2899SCharles.Forsyth /* for the font scaler */ 6394*37da2899SCharles.Forsyth if ( ( args[0] & 1 ) != 0 ) 6395*37da2899SCharles.Forsyth K = 3; 6396*37da2899SCharles.Forsyth 6397*37da2899SCharles.Forsyth /* Has the glyph been rotated ? */ 6398*37da2899SCharles.Forsyth if ( CUR.tt_metrics.rotated ) 6399*37da2899SCharles.Forsyth K |= 0x80; 6400*37da2899SCharles.Forsyth 6401*37da2899SCharles.Forsyth /* Has the glyph been stretched ? */ 6402*37da2899SCharles.Forsyth if ( CUR.tt_metrics.stretched ) 6403*37da2899SCharles.Forsyth K |= 0x100; 6404*37da2899SCharles.Forsyth 6405*37da2899SCharles.Forsyth args[0] = K; 6406*37da2899SCharles.Forsyth } 6407*37da2899SCharles.Forsyth 6408*37da2899SCharles.Forsyth 6409*37da2899SCharles.Forsyth static void Ins_UNKNOWN(INS_ARG)6410*37da2899SCharles.Forsyth Ins_UNKNOWN( INS_ARG ) 6411*37da2899SCharles.Forsyth { 6412*37da2899SCharles.Forsyth TT_DefRecord* def = CUR.IDefs; 6413*37da2899SCharles.Forsyth TT_DefRecord* limit = def + CUR.numIDefs; 6414*37da2899SCharles.Forsyth 6415*37da2899SCharles.Forsyth FT_UNUSED_ARG; 6416*37da2899SCharles.Forsyth 6417*37da2899SCharles.Forsyth 6418*37da2899SCharles.Forsyth for ( ; def < limit; def++ ) 6419*37da2899SCharles.Forsyth { 6420*37da2899SCharles.Forsyth if ( (FT_Byte)def->opc == CUR.opcode && def->active ) 6421*37da2899SCharles.Forsyth { 6422*37da2899SCharles.Forsyth TT_CallRec* call; 6423*37da2899SCharles.Forsyth 6424*37da2899SCharles.Forsyth 6425*37da2899SCharles.Forsyth if ( CUR.callTop >= CUR.callSize ) 6426*37da2899SCharles.Forsyth { 6427*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 6428*37da2899SCharles.Forsyth return; 6429*37da2899SCharles.Forsyth } 6430*37da2899SCharles.Forsyth 6431*37da2899SCharles.Forsyth call = CUR.callStack + CUR.callTop++; 6432*37da2899SCharles.Forsyth 6433*37da2899SCharles.Forsyth call->Caller_Range = CUR.curRange; 6434*37da2899SCharles.Forsyth call->Caller_IP = CUR.IP+1; 6435*37da2899SCharles.Forsyth call->Cur_Count = 1; 6436*37da2899SCharles.Forsyth call->Cur_Restart = def->start; 6437*37da2899SCharles.Forsyth 6438*37da2899SCharles.Forsyth INS_Goto_CodeRange( def->range, def->start ); 6439*37da2899SCharles.Forsyth 6440*37da2899SCharles.Forsyth CUR.step_ins = FALSE; 6441*37da2899SCharles.Forsyth return; 6442*37da2899SCharles.Forsyth } 6443*37da2899SCharles.Forsyth } 6444*37da2899SCharles.Forsyth 6445*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Opcode; 6446*37da2899SCharles.Forsyth } 6447*37da2899SCharles.Forsyth 6448*37da2899SCharles.Forsyth 6449*37da2899SCharles.Forsyth #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH 6450*37da2899SCharles.Forsyth 6451*37da2899SCharles.Forsyth 6452*37da2899SCharles.Forsyth static 6453*37da2899SCharles.Forsyth TInstruction_Function Instruct_Dispatch[256] = 6454*37da2899SCharles.Forsyth { 6455*37da2899SCharles.Forsyth /* Opcodes are gathered in groups of 16. */ 6456*37da2899SCharles.Forsyth /* Please keep the spaces as they are. */ 6457*37da2899SCharles.Forsyth 6458*37da2899SCharles.Forsyth /* SVTCA y */ Ins_SVTCA, 6459*37da2899SCharles.Forsyth /* SVTCA x */ Ins_SVTCA, 6460*37da2899SCharles.Forsyth /* SPvTCA y */ Ins_SPVTCA, 6461*37da2899SCharles.Forsyth /* SPvTCA x */ Ins_SPVTCA, 6462*37da2899SCharles.Forsyth /* SFvTCA y */ Ins_SFVTCA, 6463*37da2899SCharles.Forsyth /* SFvTCA x */ Ins_SFVTCA, 6464*37da2899SCharles.Forsyth /* SPvTL // */ Ins_SPVTL, 6465*37da2899SCharles.Forsyth /* SPvTL + */ Ins_SPVTL, 6466*37da2899SCharles.Forsyth /* SFvTL // */ Ins_SFVTL, 6467*37da2899SCharles.Forsyth /* SFvTL + */ Ins_SFVTL, 6468*37da2899SCharles.Forsyth /* SPvFS */ Ins_SPVFS, 6469*37da2899SCharles.Forsyth /* SFvFS */ Ins_SFVFS, 6470*37da2899SCharles.Forsyth /* GPV */ Ins_GPV, 6471*37da2899SCharles.Forsyth /* GFV */ Ins_GFV, 6472*37da2899SCharles.Forsyth /* SFvTPv */ Ins_SFVTPV, 6473*37da2899SCharles.Forsyth /* ISECT */ Ins_ISECT, 6474*37da2899SCharles.Forsyth 6475*37da2899SCharles.Forsyth /* SRP0 */ Ins_SRP0, 6476*37da2899SCharles.Forsyth /* SRP1 */ Ins_SRP1, 6477*37da2899SCharles.Forsyth /* SRP2 */ Ins_SRP2, 6478*37da2899SCharles.Forsyth /* SZP0 */ Ins_SZP0, 6479*37da2899SCharles.Forsyth /* SZP1 */ Ins_SZP1, 6480*37da2899SCharles.Forsyth /* SZP2 */ Ins_SZP2, 6481*37da2899SCharles.Forsyth /* SZPS */ Ins_SZPS, 6482*37da2899SCharles.Forsyth /* SLOOP */ Ins_SLOOP, 6483*37da2899SCharles.Forsyth /* RTG */ Ins_RTG, 6484*37da2899SCharles.Forsyth /* RTHG */ Ins_RTHG, 6485*37da2899SCharles.Forsyth /* SMD */ Ins_SMD, 6486*37da2899SCharles.Forsyth /* ELSE */ Ins_ELSE, 6487*37da2899SCharles.Forsyth /* JMPR */ Ins_JMPR, 6488*37da2899SCharles.Forsyth /* SCvTCi */ Ins_SCVTCI, 6489*37da2899SCharles.Forsyth /* SSwCi */ Ins_SSWCI, 6490*37da2899SCharles.Forsyth /* SSW */ Ins_SSW, 6491*37da2899SCharles.Forsyth 6492*37da2899SCharles.Forsyth /* DUP */ Ins_DUP, 6493*37da2899SCharles.Forsyth /* POP */ Ins_POP, 6494*37da2899SCharles.Forsyth /* CLEAR */ Ins_CLEAR, 6495*37da2899SCharles.Forsyth /* SWAP */ Ins_SWAP, 6496*37da2899SCharles.Forsyth /* DEPTH */ Ins_DEPTH, 6497*37da2899SCharles.Forsyth /* CINDEX */ Ins_CINDEX, 6498*37da2899SCharles.Forsyth /* MINDEX */ Ins_MINDEX, 6499*37da2899SCharles.Forsyth /* AlignPTS */ Ins_ALIGNPTS, 6500*37da2899SCharles.Forsyth /* INS_0x28 */ Ins_UNKNOWN, 6501*37da2899SCharles.Forsyth /* UTP */ Ins_UTP, 6502*37da2899SCharles.Forsyth /* LOOPCALL */ Ins_LOOPCALL, 6503*37da2899SCharles.Forsyth /* CALL */ Ins_CALL, 6504*37da2899SCharles.Forsyth /* FDEF */ Ins_FDEF, 6505*37da2899SCharles.Forsyth /* ENDF */ Ins_ENDF, 6506*37da2899SCharles.Forsyth /* MDAP[0] */ Ins_MDAP, 6507*37da2899SCharles.Forsyth /* MDAP[1] */ Ins_MDAP, 6508*37da2899SCharles.Forsyth 6509*37da2899SCharles.Forsyth /* IUP[0] */ Ins_IUP, 6510*37da2899SCharles.Forsyth /* IUP[1] */ Ins_IUP, 6511*37da2899SCharles.Forsyth /* SHP[0] */ Ins_SHP, 6512*37da2899SCharles.Forsyth /* SHP[1] */ Ins_SHP, 6513*37da2899SCharles.Forsyth /* SHC[0] */ Ins_SHC, 6514*37da2899SCharles.Forsyth /* SHC[1] */ Ins_SHC, 6515*37da2899SCharles.Forsyth /* SHZ[0] */ Ins_SHZ, 6516*37da2899SCharles.Forsyth /* SHZ[1] */ Ins_SHZ, 6517*37da2899SCharles.Forsyth /* SHPIX */ Ins_SHPIX, 6518*37da2899SCharles.Forsyth /* IP */ Ins_IP, 6519*37da2899SCharles.Forsyth /* MSIRP[0] */ Ins_MSIRP, 6520*37da2899SCharles.Forsyth /* MSIRP[1] */ Ins_MSIRP, 6521*37da2899SCharles.Forsyth /* AlignRP */ Ins_ALIGNRP, 6522*37da2899SCharles.Forsyth /* RTDG */ Ins_RTDG, 6523*37da2899SCharles.Forsyth /* MIAP[0] */ Ins_MIAP, 6524*37da2899SCharles.Forsyth /* MIAP[1] */ Ins_MIAP, 6525*37da2899SCharles.Forsyth 6526*37da2899SCharles.Forsyth /* NPushB */ Ins_NPUSHB, 6527*37da2899SCharles.Forsyth /* NPushW */ Ins_NPUSHW, 6528*37da2899SCharles.Forsyth /* WS */ Ins_WS, 6529*37da2899SCharles.Forsyth /* RS */ Ins_RS, 6530*37da2899SCharles.Forsyth /* WCvtP */ Ins_WCVTP, 6531*37da2899SCharles.Forsyth /* RCvt */ Ins_RCVT, 6532*37da2899SCharles.Forsyth /* GC[0] */ Ins_GC, 6533*37da2899SCharles.Forsyth /* GC[1] */ Ins_GC, 6534*37da2899SCharles.Forsyth /* SCFS */ Ins_SCFS, 6535*37da2899SCharles.Forsyth /* MD[0] */ Ins_MD, 6536*37da2899SCharles.Forsyth /* MD[1] */ Ins_MD, 6537*37da2899SCharles.Forsyth /* MPPEM */ Ins_MPPEM, 6538*37da2899SCharles.Forsyth /* MPS */ Ins_MPS, 6539*37da2899SCharles.Forsyth /* FlipON */ Ins_FLIPON, 6540*37da2899SCharles.Forsyth /* FlipOFF */ Ins_FLIPOFF, 6541*37da2899SCharles.Forsyth /* DEBUG */ Ins_DEBUG, 6542*37da2899SCharles.Forsyth 6543*37da2899SCharles.Forsyth /* LT */ Ins_LT, 6544*37da2899SCharles.Forsyth /* LTEQ */ Ins_LTEQ, 6545*37da2899SCharles.Forsyth /* GT */ Ins_GT, 6546*37da2899SCharles.Forsyth /* GTEQ */ Ins_GTEQ, 6547*37da2899SCharles.Forsyth /* EQ */ Ins_EQ, 6548*37da2899SCharles.Forsyth /* NEQ */ Ins_NEQ, 6549*37da2899SCharles.Forsyth /* ODD */ Ins_ODD, 6550*37da2899SCharles.Forsyth /* EVEN */ Ins_EVEN, 6551*37da2899SCharles.Forsyth /* IF */ Ins_IF, 6552*37da2899SCharles.Forsyth /* EIF */ Ins_EIF, 6553*37da2899SCharles.Forsyth /* AND */ Ins_AND, 6554*37da2899SCharles.Forsyth /* OR */ Ins_OR, 6555*37da2899SCharles.Forsyth /* NOT */ Ins_NOT, 6556*37da2899SCharles.Forsyth /* DeltaP1 */ Ins_DELTAP, 6557*37da2899SCharles.Forsyth /* SDB */ Ins_SDB, 6558*37da2899SCharles.Forsyth /* SDS */ Ins_SDS, 6559*37da2899SCharles.Forsyth 6560*37da2899SCharles.Forsyth /* ADD */ Ins_ADD, 6561*37da2899SCharles.Forsyth /* SUB */ Ins_SUB, 6562*37da2899SCharles.Forsyth /* DIV */ Ins_DIV, 6563*37da2899SCharles.Forsyth /* MUL */ Ins_MUL, 6564*37da2899SCharles.Forsyth /* ABS */ Ins_ABS, 6565*37da2899SCharles.Forsyth /* NEG */ Ins_NEG, 6566*37da2899SCharles.Forsyth /* FLOOR */ Ins_FLOOR, 6567*37da2899SCharles.Forsyth /* CEILING */ Ins_CEILING, 6568*37da2899SCharles.Forsyth /* ROUND[0] */ Ins_ROUND, 6569*37da2899SCharles.Forsyth /* ROUND[1] */ Ins_ROUND, 6570*37da2899SCharles.Forsyth /* ROUND[2] */ Ins_ROUND, 6571*37da2899SCharles.Forsyth /* ROUND[3] */ Ins_ROUND, 6572*37da2899SCharles.Forsyth /* NROUND[0] */ Ins_NROUND, 6573*37da2899SCharles.Forsyth /* NROUND[1] */ Ins_NROUND, 6574*37da2899SCharles.Forsyth /* NROUND[2] */ Ins_NROUND, 6575*37da2899SCharles.Forsyth /* NROUND[3] */ Ins_NROUND, 6576*37da2899SCharles.Forsyth 6577*37da2899SCharles.Forsyth /* WCvtF */ Ins_WCVTF, 6578*37da2899SCharles.Forsyth /* DeltaP2 */ Ins_DELTAP, 6579*37da2899SCharles.Forsyth /* DeltaP3 */ Ins_DELTAP, 6580*37da2899SCharles.Forsyth /* DeltaCn[0] */ Ins_DELTAC, 6581*37da2899SCharles.Forsyth /* DeltaCn[1] */ Ins_DELTAC, 6582*37da2899SCharles.Forsyth /* DeltaCn[2] */ Ins_DELTAC, 6583*37da2899SCharles.Forsyth /* SROUND */ Ins_SROUND, 6584*37da2899SCharles.Forsyth /* S45Round */ Ins_S45ROUND, 6585*37da2899SCharles.Forsyth /* JROT */ Ins_JROT, 6586*37da2899SCharles.Forsyth /* JROF */ Ins_JROF, 6587*37da2899SCharles.Forsyth /* ROFF */ Ins_ROFF, 6588*37da2899SCharles.Forsyth /* INS_0x7B */ Ins_UNKNOWN, 6589*37da2899SCharles.Forsyth /* RUTG */ Ins_RUTG, 6590*37da2899SCharles.Forsyth /* RDTG */ Ins_RDTG, 6591*37da2899SCharles.Forsyth /* SANGW */ Ins_SANGW, 6592*37da2899SCharles.Forsyth /* AA */ Ins_AA, 6593*37da2899SCharles.Forsyth 6594*37da2899SCharles.Forsyth /* FlipPT */ Ins_FLIPPT, 6595*37da2899SCharles.Forsyth /* FlipRgON */ Ins_FLIPRGON, 6596*37da2899SCharles.Forsyth /* FlipRgOFF */ Ins_FLIPRGOFF, 6597*37da2899SCharles.Forsyth /* INS_0x83 */ Ins_UNKNOWN, 6598*37da2899SCharles.Forsyth /* INS_0x84 */ Ins_UNKNOWN, 6599*37da2899SCharles.Forsyth /* ScanCTRL */ Ins_SCANCTRL, 6600*37da2899SCharles.Forsyth /* SDPVTL[0] */ Ins_SDPVTL, 6601*37da2899SCharles.Forsyth /* SDPVTL[1] */ Ins_SDPVTL, 6602*37da2899SCharles.Forsyth /* GetINFO */ Ins_GETINFO, 6603*37da2899SCharles.Forsyth /* IDEF */ Ins_IDEF, 6604*37da2899SCharles.Forsyth /* ROLL */ Ins_ROLL, 6605*37da2899SCharles.Forsyth /* MAX */ Ins_MAX, 6606*37da2899SCharles.Forsyth /* MIN */ Ins_MIN, 6607*37da2899SCharles.Forsyth /* ScanTYPE */ Ins_SCANTYPE, 6608*37da2899SCharles.Forsyth /* InstCTRL */ Ins_INSTCTRL, 6609*37da2899SCharles.Forsyth /* INS_0x8F */ Ins_UNKNOWN, 6610*37da2899SCharles.Forsyth 6611*37da2899SCharles.Forsyth /* INS_0x90 */ Ins_UNKNOWN, 6612*37da2899SCharles.Forsyth /* INS_0x91 */ Ins_UNKNOWN, 6613*37da2899SCharles.Forsyth /* INS_0x92 */ Ins_UNKNOWN, 6614*37da2899SCharles.Forsyth /* INS_0x93 */ Ins_UNKNOWN, 6615*37da2899SCharles.Forsyth /* INS_0x94 */ Ins_UNKNOWN, 6616*37da2899SCharles.Forsyth /* INS_0x95 */ Ins_UNKNOWN, 6617*37da2899SCharles.Forsyth /* INS_0x96 */ Ins_UNKNOWN, 6618*37da2899SCharles.Forsyth /* INS_0x97 */ Ins_UNKNOWN, 6619*37da2899SCharles.Forsyth /* INS_0x98 */ Ins_UNKNOWN, 6620*37da2899SCharles.Forsyth /* INS_0x99 */ Ins_UNKNOWN, 6621*37da2899SCharles.Forsyth /* INS_0x9A */ Ins_UNKNOWN, 6622*37da2899SCharles.Forsyth /* INS_0x9B */ Ins_UNKNOWN, 6623*37da2899SCharles.Forsyth /* INS_0x9C */ Ins_UNKNOWN, 6624*37da2899SCharles.Forsyth /* INS_0x9D */ Ins_UNKNOWN, 6625*37da2899SCharles.Forsyth /* INS_0x9E */ Ins_UNKNOWN, 6626*37da2899SCharles.Forsyth /* INS_0x9F */ Ins_UNKNOWN, 6627*37da2899SCharles.Forsyth 6628*37da2899SCharles.Forsyth /* INS_0xA0 */ Ins_UNKNOWN, 6629*37da2899SCharles.Forsyth /* INS_0xA1 */ Ins_UNKNOWN, 6630*37da2899SCharles.Forsyth /* INS_0xA2 */ Ins_UNKNOWN, 6631*37da2899SCharles.Forsyth /* INS_0xA3 */ Ins_UNKNOWN, 6632*37da2899SCharles.Forsyth /* INS_0xA4 */ Ins_UNKNOWN, 6633*37da2899SCharles.Forsyth /* INS_0xA5 */ Ins_UNKNOWN, 6634*37da2899SCharles.Forsyth /* INS_0xA6 */ Ins_UNKNOWN, 6635*37da2899SCharles.Forsyth /* INS_0xA7 */ Ins_UNKNOWN, 6636*37da2899SCharles.Forsyth /* INS_0xA8 */ Ins_UNKNOWN, 6637*37da2899SCharles.Forsyth /* INS_0xA9 */ Ins_UNKNOWN, 6638*37da2899SCharles.Forsyth /* INS_0xAA */ Ins_UNKNOWN, 6639*37da2899SCharles.Forsyth /* INS_0xAB */ Ins_UNKNOWN, 6640*37da2899SCharles.Forsyth /* INS_0xAC */ Ins_UNKNOWN, 6641*37da2899SCharles.Forsyth /* INS_0xAD */ Ins_UNKNOWN, 6642*37da2899SCharles.Forsyth /* INS_0xAE */ Ins_UNKNOWN, 6643*37da2899SCharles.Forsyth /* INS_0xAF */ Ins_UNKNOWN, 6644*37da2899SCharles.Forsyth 6645*37da2899SCharles.Forsyth /* PushB[0] */ Ins_PUSHB, 6646*37da2899SCharles.Forsyth /* PushB[1] */ Ins_PUSHB, 6647*37da2899SCharles.Forsyth /* PushB[2] */ Ins_PUSHB, 6648*37da2899SCharles.Forsyth /* PushB[3] */ Ins_PUSHB, 6649*37da2899SCharles.Forsyth /* PushB[4] */ Ins_PUSHB, 6650*37da2899SCharles.Forsyth /* PushB[5] */ Ins_PUSHB, 6651*37da2899SCharles.Forsyth /* PushB[6] */ Ins_PUSHB, 6652*37da2899SCharles.Forsyth /* PushB[7] */ Ins_PUSHB, 6653*37da2899SCharles.Forsyth /* PushW[0] */ Ins_PUSHW, 6654*37da2899SCharles.Forsyth /* PushW[1] */ Ins_PUSHW, 6655*37da2899SCharles.Forsyth /* PushW[2] */ Ins_PUSHW, 6656*37da2899SCharles.Forsyth /* PushW[3] */ Ins_PUSHW, 6657*37da2899SCharles.Forsyth /* PushW[4] */ Ins_PUSHW, 6658*37da2899SCharles.Forsyth /* PushW[5] */ Ins_PUSHW, 6659*37da2899SCharles.Forsyth /* PushW[6] */ Ins_PUSHW, 6660*37da2899SCharles.Forsyth /* PushW[7] */ Ins_PUSHW, 6661*37da2899SCharles.Forsyth 6662*37da2899SCharles.Forsyth /* MDRP[00] */ Ins_MDRP, 6663*37da2899SCharles.Forsyth /* MDRP[01] */ Ins_MDRP, 6664*37da2899SCharles.Forsyth /* MDRP[02] */ Ins_MDRP, 6665*37da2899SCharles.Forsyth /* MDRP[03] */ Ins_MDRP, 6666*37da2899SCharles.Forsyth /* MDRP[04] */ Ins_MDRP, 6667*37da2899SCharles.Forsyth /* MDRP[05] */ Ins_MDRP, 6668*37da2899SCharles.Forsyth /* MDRP[06] */ Ins_MDRP, 6669*37da2899SCharles.Forsyth /* MDRP[07] */ Ins_MDRP, 6670*37da2899SCharles.Forsyth /* MDRP[08] */ Ins_MDRP, 6671*37da2899SCharles.Forsyth /* MDRP[09] */ Ins_MDRP, 6672*37da2899SCharles.Forsyth /* MDRP[10] */ Ins_MDRP, 6673*37da2899SCharles.Forsyth /* MDRP[11] */ Ins_MDRP, 6674*37da2899SCharles.Forsyth /* MDRP[12] */ Ins_MDRP, 6675*37da2899SCharles.Forsyth /* MDRP[13] */ Ins_MDRP, 6676*37da2899SCharles.Forsyth /* MDRP[14] */ Ins_MDRP, 6677*37da2899SCharles.Forsyth /* MDRP[15] */ Ins_MDRP, 6678*37da2899SCharles.Forsyth 6679*37da2899SCharles.Forsyth /* MDRP[16] */ Ins_MDRP, 6680*37da2899SCharles.Forsyth /* MDRP[17] */ Ins_MDRP, 6681*37da2899SCharles.Forsyth /* MDRP[18] */ Ins_MDRP, 6682*37da2899SCharles.Forsyth /* MDRP[19] */ Ins_MDRP, 6683*37da2899SCharles.Forsyth /* MDRP[20] */ Ins_MDRP, 6684*37da2899SCharles.Forsyth /* MDRP[21] */ Ins_MDRP, 6685*37da2899SCharles.Forsyth /* MDRP[22] */ Ins_MDRP, 6686*37da2899SCharles.Forsyth /* MDRP[23] */ Ins_MDRP, 6687*37da2899SCharles.Forsyth /* MDRP[24] */ Ins_MDRP, 6688*37da2899SCharles.Forsyth /* MDRP[25] */ Ins_MDRP, 6689*37da2899SCharles.Forsyth /* MDRP[26] */ Ins_MDRP, 6690*37da2899SCharles.Forsyth /* MDRP[27] */ Ins_MDRP, 6691*37da2899SCharles.Forsyth /* MDRP[28] */ Ins_MDRP, 6692*37da2899SCharles.Forsyth /* MDRP[29] */ Ins_MDRP, 6693*37da2899SCharles.Forsyth /* MDRP[30] */ Ins_MDRP, 6694*37da2899SCharles.Forsyth /* MDRP[31] */ Ins_MDRP, 6695*37da2899SCharles.Forsyth 6696*37da2899SCharles.Forsyth /* MIRP[00] */ Ins_MIRP, 6697*37da2899SCharles.Forsyth /* MIRP[01] */ Ins_MIRP, 6698*37da2899SCharles.Forsyth /* MIRP[02] */ Ins_MIRP, 6699*37da2899SCharles.Forsyth /* MIRP[03] */ Ins_MIRP, 6700*37da2899SCharles.Forsyth /* MIRP[04] */ Ins_MIRP, 6701*37da2899SCharles.Forsyth /* MIRP[05] */ Ins_MIRP, 6702*37da2899SCharles.Forsyth /* MIRP[06] */ Ins_MIRP, 6703*37da2899SCharles.Forsyth /* MIRP[07] */ Ins_MIRP, 6704*37da2899SCharles.Forsyth /* MIRP[08] */ Ins_MIRP, 6705*37da2899SCharles.Forsyth /* MIRP[09] */ Ins_MIRP, 6706*37da2899SCharles.Forsyth /* MIRP[10] */ Ins_MIRP, 6707*37da2899SCharles.Forsyth /* MIRP[11] */ Ins_MIRP, 6708*37da2899SCharles.Forsyth /* MIRP[12] */ Ins_MIRP, 6709*37da2899SCharles.Forsyth /* MIRP[13] */ Ins_MIRP, 6710*37da2899SCharles.Forsyth /* MIRP[14] */ Ins_MIRP, 6711*37da2899SCharles.Forsyth /* MIRP[15] */ Ins_MIRP, 6712*37da2899SCharles.Forsyth 6713*37da2899SCharles.Forsyth /* MIRP[16] */ Ins_MIRP, 6714*37da2899SCharles.Forsyth /* MIRP[17] */ Ins_MIRP, 6715*37da2899SCharles.Forsyth /* MIRP[18] */ Ins_MIRP, 6716*37da2899SCharles.Forsyth /* MIRP[19] */ Ins_MIRP, 6717*37da2899SCharles.Forsyth /* MIRP[20] */ Ins_MIRP, 6718*37da2899SCharles.Forsyth /* MIRP[21] */ Ins_MIRP, 6719*37da2899SCharles.Forsyth /* MIRP[22] */ Ins_MIRP, 6720*37da2899SCharles.Forsyth /* MIRP[23] */ Ins_MIRP, 6721*37da2899SCharles.Forsyth /* MIRP[24] */ Ins_MIRP, 6722*37da2899SCharles.Forsyth /* MIRP[25] */ Ins_MIRP, 6723*37da2899SCharles.Forsyth /* MIRP[26] */ Ins_MIRP, 6724*37da2899SCharles.Forsyth /* MIRP[27] */ Ins_MIRP, 6725*37da2899SCharles.Forsyth /* MIRP[28] */ Ins_MIRP, 6726*37da2899SCharles.Forsyth /* MIRP[29] */ Ins_MIRP, 6727*37da2899SCharles.Forsyth /* MIRP[30] */ Ins_MIRP, 6728*37da2899SCharles.Forsyth /* MIRP[31] */ Ins_MIRP 6729*37da2899SCharles.Forsyth }; 6730*37da2899SCharles.Forsyth 6731*37da2899SCharles.Forsyth 6732*37da2899SCharles.Forsyth #endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ 6733*37da2899SCharles.Forsyth 6734*37da2899SCharles.Forsyth 6735*37da2899SCharles.Forsyth /*************************************************************************/ 6736*37da2899SCharles.Forsyth /* */ 6737*37da2899SCharles.Forsyth /* RUN */ 6738*37da2899SCharles.Forsyth /* */ 6739*37da2899SCharles.Forsyth /* This function executes a run of opcodes. It will exit in the */ 6740*37da2899SCharles.Forsyth /* following cases: */ 6741*37da2899SCharles.Forsyth /* */ 6742*37da2899SCharles.Forsyth /* - Errors (in which case it returns FALSE). */ 6743*37da2899SCharles.Forsyth /* */ 6744*37da2899SCharles.Forsyth /* - Reaching the end of the main code range (returns TRUE). */ 6745*37da2899SCharles.Forsyth /* Reaching the end of a code range within a function call is an */ 6746*37da2899SCharles.Forsyth /* error. */ 6747*37da2899SCharles.Forsyth /* */ 6748*37da2899SCharles.Forsyth /* - After executing one single opcode, if the flag `Instruction_Trap' */ 6749*37da2899SCharles.Forsyth /* is set to TRUE (returns TRUE). */ 6750*37da2899SCharles.Forsyth /* */ 6751*37da2899SCharles.Forsyth /* On exit whith TRUE, test IP < CodeSize to know wether it comes from */ 6752*37da2899SCharles.Forsyth /* an instruction trap or a normal termination. */ 6753*37da2899SCharles.Forsyth /* */ 6754*37da2899SCharles.Forsyth /* */ 6755*37da2899SCharles.Forsyth /* Note: The documented DEBUG opcode pops a value from the stack. This */ 6756*37da2899SCharles.Forsyth /* behaviour is unsupported; here a DEBUG opcode is always an */ 6757*37da2899SCharles.Forsyth /* error. */ 6758*37da2899SCharles.Forsyth /* */ 6759*37da2899SCharles.Forsyth /* */ 6760*37da2899SCharles.Forsyth /* THIS IS THE INTERPRETER'S MAIN LOOP. */ 6761*37da2899SCharles.Forsyth /* */ 6762*37da2899SCharles.Forsyth /* Instructions appear in the specification's order. */ 6763*37da2899SCharles.Forsyth /* */ 6764*37da2899SCharles.Forsyth /*************************************************************************/ 6765*37da2899SCharles.Forsyth 6766*37da2899SCharles.Forsyth 6767*37da2899SCharles.Forsyth /* documentation is in ttinterp.h */ 6768*37da2899SCharles.Forsyth 6769*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) TT_RunIns(TT_ExecContext exc)6770*37da2899SCharles.Forsyth TT_RunIns( TT_ExecContext exc ) 6771*37da2899SCharles.Forsyth { 6772*37da2899SCharles.Forsyth FT_Long ins_counter = 0; /* executed instructions counter */ 6773*37da2899SCharles.Forsyth 6774*37da2899SCharles.Forsyth 6775*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_STATIC_RASTER 6776*37da2899SCharles.Forsyth cur = *exc; 6777*37da2899SCharles.Forsyth #endif 6778*37da2899SCharles.Forsyth 6779*37da2899SCharles.Forsyth /* set CVT functions */ 6780*37da2899SCharles.Forsyth CUR.tt_metrics.ratio = 0; 6781*37da2899SCharles.Forsyth if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) 6782*37da2899SCharles.Forsyth { 6783*37da2899SCharles.Forsyth /* non-square pixels, use the stretched routines */ 6784*37da2899SCharles.Forsyth CUR.func_read_cvt = Read_CVT_Stretched; 6785*37da2899SCharles.Forsyth CUR.func_write_cvt = Write_CVT_Stretched; 6786*37da2899SCharles.Forsyth CUR.func_move_cvt = Move_CVT_Stretched; 6787*37da2899SCharles.Forsyth } 6788*37da2899SCharles.Forsyth else 6789*37da2899SCharles.Forsyth { 6790*37da2899SCharles.Forsyth /* square pixels, use normal routines */ 6791*37da2899SCharles.Forsyth CUR.func_read_cvt = Read_CVT; 6792*37da2899SCharles.Forsyth CUR.func_write_cvt = Write_CVT; 6793*37da2899SCharles.Forsyth CUR.func_move_cvt = Move_CVT; 6794*37da2899SCharles.Forsyth } 6795*37da2899SCharles.Forsyth 6796*37da2899SCharles.Forsyth COMPUTE_Funcs(); 6797*37da2899SCharles.Forsyth COMPUTE_Round( (FT_Byte)exc->GS.round_state ); 6798*37da2899SCharles.Forsyth 6799*37da2899SCharles.Forsyth do 6800*37da2899SCharles.Forsyth { 6801*37da2899SCharles.Forsyth CUR.opcode = CUR.code[CUR.IP]; 6802*37da2899SCharles.Forsyth 6803*37da2899SCharles.Forsyth if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) 6804*37da2899SCharles.Forsyth { 6805*37da2899SCharles.Forsyth if ( CUR.IP + 1 > CUR.codeSize ) 6806*37da2899SCharles.Forsyth goto LErrorCodeOverflow_; 6807*37da2899SCharles.Forsyth 6808*37da2899SCharles.Forsyth CUR.length = CUR.code[CUR.IP + 1] + 2; 6809*37da2899SCharles.Forsyth } 6810*37da2899SCharles.Forsyth 6811*37da2899SCharles.Forsyth if ( CUR.IP + CUR.length > CUR.codeSize ) 6812*37da2899SCharles.Forsyth goto LErrorCodeOverflow_; 6813*37da2899SCharles.Forsyth 6814*37da2899SCharles.Forsyth /* First, let's check for empty stack and overflow */ 6815*37da2899SCharles.Forsyth CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); 6816*37da2899SCharles.Forsyth 6817*37da2899SCharles.Forsyth /* `args' is the top of the stack once arguments have been popped. */ 6818*37da2899SCharles.Forsyth /* One can also interpret it as the index of the last argument. */ 6819*37da2899SCharles.Forsyth if ( CUR.args < 0 ) 6820*37da2899SCharles.Forsyth { 6821*37da2899SCharles.Forsyth CUR.error = TT_Err_Too_Few_Arguments; 6822*37da2899SCharles.Forsyth goto LErrorLabel_; 6823*37da2899SCharles.Forsyth } 6824*37da2899SCharles.Forsyth 6825*37da2899SCharles.Forsyth CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); 6826*37da2899SCharles.Forsyth 6827*37da2899SCharles.Forsyth /* `new_top' is the new top of the stack, after the instruction's */ 6828*37da2899SCharles.Forsyth /* execution. `top' will be set to `new_top' after the `switch' */ 6829*37da2899SCharles.Forsyth /* statement. */ 6830*37da2899SCharles.Forsyth if ( CUR.new_top > CUR.stackSize ) 6831*37da2899SCharles.Forsyth { 6832*37da2899SCharles.Forsyth CUR.error = TT_Err_Stack_Overflow; 6833*37da2899SCharles.Forsyth goto LErrorLabel_; 6834*37da2899SCharles.Forsyth } 6835*37da2899SCharles.Forsyth 6836*37da2899SCharles.Forsyth CUR.step_ins = TRUE; 6837*37da2899SCharles.Forsyth CUR.error = TT_Err_Ok; 6838*37da2899SCharles.Forsyth 6839*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH 6840*37da2899SCharles.Forsyth 6841*37da2899SCharles.Forsyth { 6842*37da2899SCharles.Forsyth FT_Long* args = CUR.stack + CUR.args; 6843*37da2899SCharles.Forsyth FT_Byte opcode = CUR.opcode; 6844*37da2899SCharles.Forsyth 6845*37da2899SCharles.Forsyth 6846*37da2899SCharles.Forsyth #undef ARRAY_BOUND_ERROR 6847*37da2899SCharles.Forsyth #define ARRAY_BOUND_ERROR goto Set_Invalid_Ref 6848*37da2899SCharles.Forsyth 6849*37da2899SCharles.Forsyth 6850*37da2899SCharles.Forsyth switch ( opcode ) 6851*37da2899SCharles.Forsyth { 6852*37da2899SCharles.Forsyth case 0x00: /* SVTCA y */ 6853*37da2899SCharles.Forsyth case 0x01: /* SVTCA x */ 6854*37da2899SCharles.Forsyth case 0x02: /* SPvTCA y */ 6855*37da2899SCharles.Forsyth case 0x03: /* SPvTCA x */ 6856*37da2899SCharles.Forsyth case 0x04: /* SFvTCA y */ 6857*37da2899SCharles.Forsyth case 0x05: /* SFvTCA x */ 6858*37da2899SCharles.Forsyth { 6859*37da2899SCharles.Forsyth FT_Short AA, BB; 6860*37da2899SCharles.Forsyth 6861*37da2899SCharles.Forsyth 6862*37da2899SCharles.Forsyth AA = (FT_Short)( ( opcode & 1 ) << 14 ); 6863*37da2899SCharles.Forsyth BB = (FT_Short)( AA ^ 0x4000 ); 6864*37da2899SCharles.Forsyth 6865*37da2899SCharles.Forsyth if ( opcode < 4 ) 6866*37da2899SCharles.Forsyth { 6867*37da2899SCharles.Forsyth CUR.GS.projVector.x = AA; 6868*37da2899SCharles.Forsyth CUR.GS.projVector.y = BB; 6869*37da2899SCharles.Forsyth 6870*37da2899SCharles.Forsyth CUR.GS.dualVector.x = AA; 6871*37da2899SCharles.Forsyth CUR.GS.dualVector.y = BB; 6872*37da2899SCharles.Forsyth } 6873*37da2899SCharles.Forsyth 6874*37da2899SCharles.Forsyth if ( ( opcode & 2 ) == 0 ) 6875*37da2899SCharles.Forsyth { 6876*37da2899SCharles.Forsyth CUR.GS.freeVector.x = AA; 6877*37da2899SCharles.Forsyth CUR.GS.freeVector.y = BB; 6878*37da2899SCharles.Forsyth } 6879*37da2899SCharles.Forsyth 6880*37da2899SCharles.Forsyth COMPUTE_Funcs(); 6881*37da2899SCharles.Forsyth } 6882*37da2899SCharles.Forsyth break; 6883*37da2899SCharles.Forsyth 6884*37da2899SCharles.Forsyth case 0x06: /* SPvTL // */ 6885*37da2899SCharles.Forsyth case 0x07: /* SPvTL + */ 6886*37da2899SCharles.Forsyth DO_SPVTL 6887*37da2899SCharles.Forsyth break; 6888*37da2899SCharles.Forsyth 6889*37da2899SCharles.Forsyth case 0x08: /* SFvTL // */ 6890*37da2899SCharles.Forsyth case 0x09: /* SFvTL + */ 6891*37da2899SCharles.Forsyth DO_SFVTL 6892*37da2899SCharles.Forsyth break; 6893*37da2899SCharles.Forsyth 6894*37da2899SCharles.Forsyth case 0x0A: /* SPvFS */ 6895*37da2899SCharles.Forsyth DO_SPVFS 6896*37da2899SCharles.Forsyth break; 6897*37da2899SCharles.Forsyth 6898*37da2899SCharles.Forsyth case 0x0B: /* SFvFS */ 6899*37da2899SCharles.Forsyth DO_SFVFS 6900*37da2899SCharles.Forsyth break; 6901*37da2899SCharles.Forsyth 6902*37da2899SCharles.Forsyth case 0x0C: /* GPV */ 6903*37da2899SCharles.Forsyth DO_GPV 6904*37da2899SCharles.Forsyth break; 6905*37da2899SCharles.Forsyth 6906*37da2899SCharles.Forsyth case 0x0D: /* GFV */ 6907*37da2899SCharles.Forsyth DO_GFV 6908*37da2899SCharles.Forsyth break; 6909*37da2899SCharles.Forsyth 6910*37da2899SCharles.Forsyth case 0x0E: /* SFvTPv */ 6911*37da2899SCharles.Forsyth DO_SFVTPV 6912*37da2899SCharles.Forsyth break; 6913*37da2899SCharles.Forsyth 6914*37da2899SCharles.Forsyth case 0x0F: /* ISECT */ 6915*37da2899SCharles.Forsyth Ins_ISECT( EXEC_ARG_ args ); 6916*37da2899SCharles.Forsyth break; 6917*37da2899SCharles.Forsyth 6918*37da2899SCharles.Forsyth case 0x10: /* SRP0 */ 6919*37da2899SCharles.Forsyth DO_SRP0 6920*37da2899SCharles.Forsyth break; 6921*37da2899SCharles.Forsyth 6922*37da2899SCharles.Forsyth case 0x11: /* SRP1 */ 6923*37da2899SCharles.Forsyth DO_SRP1 6924*37da2899SCharles.Forsyth break; 6925*37da2899SCharles.Forsyth 6926*37da2899SCharles.Forsyth case 0x12: /* SRP2 */ 6927*37da2899SCharles.Forsyth DO_SRP2 6928*37da2899SCharles.Forsyth break; 6929*37da2899SCharles.Forsyth 6930*37da2899SCharles.Forsyth case 0x13: /* SZP0 */ 6931*37da2899SCharles.Forsyth Ins_SZP0( EXEC_ARG_ args ); 6932*37da2899SCharles.Forsyth break; 6933*37da2899SCharles.Forsyth 6934*37da2899SCharles.Forsyth case 0x14: /* SZP1 */ 6935*37da2899SCharles.Forsyth Ins_SZP1( EXEC_ARG_ args ); 6936*37da2899SCharles.Forsyth break; 6937*37da2899SCharles.Forsyth 6938*37da2899SCharles.Forsyth case 0x15: /* SZP2 */ 6939*37da2899SCharles.Forsyth Ins_SZP2( EXEC_ARG_ args ); 6940*37da2899SCharles.Forsyth break; 6941*37da2899SCharles.Forsyth 6942*37da2899SCharles.Forsyth case 0x16: /* SZPS */ 6943*37da2899SCharles.Forsyth Ins_SZPS( EXEC_ARG_ args ); 6944*37da2899SCharles.Forsyth break; 6945*37da2899SCharles.Forsyth 6946*37da2899SCharles.Forsyth case 0x17: /* SLOOP */ 6947*37da2899SCharles.Forsyth DO_SLOOP 6948*37da2899SCharles.Forsyth break; 6949*37da2899SCharles.Forsyth 6950*37da2899SCharles.Forsyth case 0x18: /* RTG */ 6951*37da2899SCharles.Forsyth DO_RTG 6952*37da2899SCharles.Forsyth break; 6953*37da2899SCharles.Forsyth 6954*37da2899SCharles.Forsyth case 0x19: /* RTHG */ 6955*37da2899SCharles.Forsyth DO_RTHG 6956*37da2899SCharles.Forsyth break; 6957*37da2899SCharles.Forsyth 6958*37da2899SCharles.Forsyth case 0x1A: /* SMD */ 6959*37da2899SCharles.Forsyth DO_SMD 6960*37da2899SCharles.Forsyth break; 6961*37da2899SCharles.Forsyth 6962*37da2899SCharles.Forsyth case 0x1B: /* ELSE */ 6963*37da2899SCharles.Forsyth Ins_ELSE( EXEC_ARG_ args ); 6964*37da2899SCharles.Forsyth break; 6965*37da2899SCharles.Forsyth 6966*37da2899SCharles.Forsyth case 0x1C: /* JMPR */ 6967*37da2899SCharles.Forsyth DO_JMPR 6968*37da2899SCharles.Forsyth break; 6969*37da2899SCharles.Forsyth 6970*37da2899SCharles.Forsyth case 0x1D: /* SCVTCI */ 6971*37da2899SCharles.Forsyth DO_SCVTCI 6972*37da2899SCharles.Forsyth break; 6973*37da2899SCharles.Forsyth 6974*37da2899SCharles.Forsyth case 0x1E: /* SSWCI */ 6975*37da2899SCharles.Forsyth DO_SSWCI 6976*37da2899SCharles.Forsyth break; 6977*37da2899SCharles.Forsyth 6978*37da2899SCharles.Forsyth case 0x1F: /* SSW */ 6979*37da2899SCharles.Forsyth DO_SSW 6980*37da2899SCharles.Forsyth break; 6981*37da2899SCharles.Forsyth 6982*37da2899SCharles.Forsyth case 0x20: /* DUP */ 6983*37da2899SCharles.Forsyth DO_DUP 6984*37da2899SCharles.Forsyth break; 6985*37da2899SCharles.Forsyth 6986*37da2899SCharles.Forsyth case 0x21: /* POP */ 6987*37da2899SCharles.Forsyth /* nothing :-) */ 6988*37da2899SCharles.Forsyth break; 6989*37da2899SCharles.Forsyth 6990*37da2899SCharles.Forsyth case 0x22: /* CLEAR */ 6991*37da2899SCharles.Forsyth DO_CLEAR 6992*37da2899SCharles.Forsyth break; 6993*37da2899SCharles.Forsyth 6994*37da2899SCharles.Forsyth case 0x23: /* SWAP */ 6995*37da2899SCharles.Forsyth DO_SWAP 6996*37da2899SCharles.Forsyth break; 6997*37da2899SCharles.Forsyth 6998*37da2899SCharles.Forsyth case 0x24: /* DEPTH */ 6999*37da2899SCharles.Forsyth DO_DEPTH 7000*37da2899SCharles.Forsyth break; 7001*37da2899SCharles.Forsyth 7002*37da2899SCharles.Forsyth case 0x25: /* CINDEX */ 7003*37da2899SCharles.Forsyth DO_CINDEX 7004*37da2899SCharles.Forsyth break; 7005*37da2899SCharles.Forsyth 7006*37da2899SCharles.Forsyth case 0x26: /* MINDEX */ 7007*37da2899SCharles.Forsyth Ins_MINDEX( EXEC_ARG_ args ); 7008*37da2899SCharles.Forsyth break; 7009*37da2899SCharles.Forsyth 7010*37da2899SCharles.Forsyth case 0x27: /* ALIGNPTS */ 7011*37da2899SCharles.Forsyth Ins_ALIGNPTS( EXEC_ARG_ args ); 7012*37da2899SCharles.Forsyth break; 7013*37da2899SCharles.Forsyth 7014*37da2899SCharles.Forsyth case 0x28: /* ???? */ 7015*37da2899SCharles.Forsyth Ins_UNKNOWN( EXEC_ARG_ args ); 7016*37da2899SCharles.Forsyth break; 7017*37da2899SCharles.Forsyth 7018*37da2899SCharles.Forsyth case 0x29: /* UTP */ 7019*37da2899SCharles.Forsyth Ins_UTP( EXEC_ARG_ args ); 7020*37da2899SCharles.Forsyth break; 7021*37da2899SCharles.Forsyth 7022*37da2899SCharles.Forsyth case 0x2A: /* LOOPCALL */ 7023*37da2899SCharles.Forsyth Ins_LOOPCALL( EXEC_ARG_ args ); 7024*37da2899SCharles.Forsyth break; 7025*37da2899SCharles.Forsyth 7026*37da2899SCharles.Forsyth case 0x2B: /* CALL */ 7027*37da2899SCharles.Forsyth Ins_CALL( EXEC_ARG_ args ); 7028*37da2899SCharles.Forsyth break; 7029*37da2899SCharles.Forsyth 7030*37da2899SCharles.Forsyth case 0x2C: /* FDEF */ 7031*37da2899SCharles.Forsyth Ins_FDEF( EXEC_ARG_ args ); 7032*37da2899SCharles.Forsyth break; 7033*37da2899SCharles.Forsyth 7034*37da2899SCharles.Forsyth case 0x2D: /* ENDF */ 7035*37da2899SCharles.Forsyth Ins_ENDF( EXEC_ARG_ args ); 7036*37da2899SCharles.Forsyth break; 7037*37da2899SCharles.Forsyth 7038*37da2899SCharles.Forsyth case 0x2E: /* MDAP */ 7039*37da2899SCharles.Forsyth case 0x2F: /* MDAP */ 7040*37da2899SCharles.Forsyth Ins_MDAP( EXEC_ARG_ args ); 7041*37da2899SCharles.Forsyth break; 7042*37da2899SCharles.Forsyth 7043*37da2899SCharles.Forsyth 7044*37da2899SCharles.Forsyth case 0x30: /* IUP */ 7045*37da2899SCharles.Forsyth case 0x31: /* IUP */ 7046*37da2899SCharles.Forsyth Ins_IUP( EXEC_ARG_ args ); 7047*37da2899SCharles.Forsyth break; 7048*37da2899SCharles.Forsyth 7049*37da2899SCharles.Forsyth case 0x32: /* SHP */ 7050*37da2899SCharles.Forsyth case 0x33: /* SHP */ 7051*37da2899SCharles.Forsyth Ins_SHP( EXEC_ARG_ args ); 7052*37da2899SCharles.Forsyth break; 7053*37da2899SCharles.Forsyth 7054*37da2899SCharles.Forsyth case 0x34: /* SHC */ 7055*37da2899SCharles.Forsyth case 0x35: /* SHC */ 7056*37da2899SCharles.Forsyth Ins_SHC( EXEC_ARG_ args ); 7057*37da2899SCharles.Forsyth break; 7058*37da2899SCharles.Forsyth 7059*37da2899SCharles.Forsyth case 0x36: /* SHZ */ 7060*37da2899SCharles.Forsyth case 0x37: /* SHZ */ 7061*37da2899SCharles.Forsyth Ins_SHZ( EXEC_ARG_ args ); 7062*37da2899SCharles.Forsyth break; 7063*37da2899SCharles.Forsyth 7064*37da2899SCharles.Forsyth case 0x38: /* SHPIX */ 7065*37da2899SCharles.Forsyth Ins_SHPIX( EXEC_ARG_ args ); 7066*37da2899SCharles.Forsyth break; 7067*37da2899SCharles.Forsyth 7068*37da2899SCharles.Forsyth case 0x39: /* IP */ 7069*37da2899SCharles.Forsyth Ins_IP( EXEC_ARG_ args ); 7070*37da2899SCharles.Forsyth break; 7071*37da2899SCharles.Forsyth 7072*37da2899SCharles.Forsyth case 0x3A: /* MSIRP */ 7073*37da2899SCharles.Forsyth case 0x3B: /* MSIRP */ 7074*37da2899SCharles.Forsyth Ins_MSIRP( EXEC_ARG_ args ); 7075*37da2899SCharles.Forsyth break; 7076*37da2899SCharles.Forsyth 7077*37da2899SCharles.Forsyth case 0x3C: /* AlignRP */ 7078*37da2899SCharles.Forsyth Ins_ALIGNRP( EXEC_ARG_ args ); 7079*37da2899SCharles.Forsyth break; 7080*37da2899SCharles.Forsyth 7081*37da2899SCharles.Forsyth case 0x3D: /* RTDG */ 7082*37da2899SCharles.Forsyth DO_RTDG 7083*37da2899SCharles.Forsyth break; 7084*37da2899SCharles.Forsyth 7085*37da2899SCharles.Forsyth case 0x3E: /* MIAP */ 7086*37da2899SCharles.Forsyth case 0x3F: /* MIAP */ 7087*37da2899SCharles.Forsyth Ins_MIAP( EXEC_ARG_ args ); 7088*37da2899SCharles.Forsyth break; 7089*37da2899SCharles.Forsyth 7090*37da2899SCharles.Forsyth case 0x40: /* NPUSHB */ 7091*37da2899SCharles.Forsyth Ins_NPUSHB( EXEC_ARG_ args ); 7092*37da2899SCharles.Forsyth break; 7093*37da2899SCharles.Forsyth 7094*37da2899SCharles.Forsyth case 0x41: /* NPUSHW */ 7095*37da2899SCharles.Forsyth Ins_NPUSHW( EXEC_ARG_ args ); 7096*37da2899SCharles.Forsyth break; 7097*37da2899SCharles.Forsyth 7098*37da2899SCharles.Forsyth case 0x42: /* WS */ 7099*37da2899SCharles.Forsyth DO_WS 7100*37da2899SCharles.Forsyth break; 7101*37da2899SCharles.Forsyth 7102*37da2899SCharles.Forsyth Set_Invalid_Ref: 7103*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 7104*37da2899SCharles.Forsyth break; 7105*37da2899SCharles.Forsyth 7106*37da2899SCharles.Forsyth case 0x43: /* RS */ 7107*37da2899SCharles.Forsyth DO_RS 7108*37da2899SCharles.Forsyth break; 7109*37da2899SCharles.Forsyth 7110*37da2899SCharles.Forsyth case 0x44: /* WCVTP */ 7111*37da2899SCharles.Forsyth DO_WCVTP 7112*37da2899SCharles.Forsyth break; 7113*37da2899SCharles.Forsyth 7114*37da2899SCharles.Forsyth case 0x45: /* RCVT */ 7115*37da2899SCharles.Forsyth DO_RCVT 7116*37da2899SCharles.Forsyth break; 7117*37da2899SCharles.Forsyth 7118*37da2899SCharles.Forsyth case 0x46: /* GC */ 7119*37da2899SCharles.Forsyth case 0x47: /* GC */ 7120*37da2899SCharles.Forsyth Ins_GC( EXEC_ARG_ args ); 7121*37da2899SCharles.Forsyth break; 7122*37da2899SCharles.Forsyth 7123*37da2899SCharles.Forsyth case 0x48: /* SCFS */ 7124*37da2899SCharles.Forsyth Ins_SCFS( EXEC_ARG_ args ); 7125*37da2899SCharles.Forsyth break; 7126*37da2899SCharles.Forsyth 7127*37da2899SCharles.Forsyth case 0x49: /* MD */ 7128*37da2899SCharles.Forsyth case 0x4A: /* MD */ 7129*37da2899SCharles.Forsyth Ins_MD( EXEC_ARG_ args ); 7130*37da2899SCharles.Forsyth break; 7131*37da2899SCharles.Forsyth 7132*37da2899SCharles.Forsyth case 0x4B: /* MPPEM */ 7133*37da2899SCharles.Forsyth DO_MPPEM 7134*37da2899SCharles.Forsyth break; 7135*37da2899SCharles.Forsyth 7136*37da2899SCharles.Forsyth case 0x4C: /* MPS */ 7137*37da2899SCharles.Forsyth DO_MPS 7138*37da2899SCharles.Forsyth break; 7139*37da2899SCharles.Forsyth 7140*37da2899SCharles.Forsyth case 0x4D: /* FLIPON */ 7141*37da2899SCharles.Forsyth DO_FLIPON 7142*37da2899SCharles.Forsyth break; 7143*37da2899SCharles.Forsyth 7144*37da2899SCharles.Forsyth case 0x4E: /* FLIPOFF */ 7145*37da2899SCharles.Forsyth DO_FLIPOFF 7146*37da2899SCharles.Forsyth break; 7147*37da2899SCharles.Forsyth 7148*37da2899SCharles.Forsyth case 0x4F: /* DEBUG */ 7149*37da2899SCharles.Forsyth DO_DEBUG 7150*37da2899SCharles.Forsyth break; 7151*37da2899SCharles.Forsyth 7152*37da2899SCharles.Forsyth case 0x50: /* LT */ 7153*37da2899SCharles.Forsyth DO_LT 7154*37da2899SCharles.Forsyth break; 7155*37da2899SCharles.Forsyth 7156*37da2899SCharles.Forsyth case 0x51: /* LTEQ */ 7157*37da2899SCharles.Forsyth DO_LTEQ 7158*37da2899SCharles.Forsyth break; 7159*37da2899SCharles.Forsyth 7160*37da2899SCharles.Forsyth case 0x52: /* GT */ 7161*37da2899SCharles.Forsyth DO_GT 7162*37da2899SCharles.Forsyth break; 7163*37da2899SCharles.Forsyth 7164*37da2899SCharles.Forsyth case 0x53: /* GTEQ */ 7165*37da2899SCharles.Forsyth DO_GTEQ 7166*37da2899SCharles.Forsyth break; 7167*37da2899SCharles.Forsyth 7168*37da2899SCharles.Forsyth case 0x54: /* EQ */ 7169*37da2899SCharles.Forsyth DO_EQ 7170*37da2899SCharles.Forsyth break; 7171*37da2899SCharles.Forsyth 7172*37da2899SCharles.Forsyth case 0x55: /* NEQ */ 7173*37da2899SCharles.Forsyth DO_NEQ 7174*37da2899SCharles.Forsyth break; 7175*37da2899SCharles.Forsyth 7176*37da2899SCharles.Forsyth case 0x56: /* ODD */ 7177*37da2899SCharles.Forsyth DO_ODD 7178*37da2899SCharles.Forsyth break; 7179*37da2899SCharles.Forsyth 7180*37da2899SCharles.Forsyth case 0x57: /* EVEN */ 7181*37da2899SCharles.Forsyth DO_EVEN 7182*37da2899SCharles.Forsyth break; 7183*37da2899SCharles.Forsyth 7184*37da2899SCharles.Forsyth case 0x58: /* IF */ 7185*37da2899SCharles.Forsyth Ins_IF( EXEC_ARG_ args ); 7186*37da2899SCharles.Forsyth break; 7187*37da2899SCharles.Forsyth 7188*37da2899SCharles.Forsyth case 0x59: /* EIF */ 7189*37da2899SCharles.Forsyth /* do nothing */ 7190*37da2899SCharles.Forsyth break; 7191*37da2899SCharles.Forsyth 7192*37da2899SCharles.Forsyth case 0x5A: /* AND */ 7193*37da2899SCharles.Forsyth DO_AND 7194*37da2899SCharles.Forsyth break; 7195*37da2899SCharles.Forsyth 7196*37da2899SCharles.Forsyth case 0x5B: /* OR */ 7197*37da2899SCharles.Forsyth DO_OR 7198*37da2899SCharles.Forsyth break; 7199*37da2899SCharles.Forsyth 7200*37da2899SCharles.Forsyth case 0x5C: /* NOT */ 7201*37da2899SCharles.Forsyth DO_NOT 7202*37da2899SCharles.Forsyth break; 7203*37da2899SCharles.Forsyth 7204*37da2899SCharles.Forsyth case 0x5D: /* DELTAP1 */ 7205*37da2899SCharles.Forsyth Ins_DELTAP( EXEC_ARG_ args ); 7206*37da2899SCharles.Forsyth break; 7207*37da2899SCharles.Forsyth 7208*37da2899SCharles.Forsyth case 0x5E: /* SDB */ 7209*37da2899SCharles.Forsyth DO_SDB 7210*37da2899SCharles.Forsyth break; 7211*37da2899SCharles.Forsyth 7212*37da2899SCharles.Forsyth case 0x5F: /* SDS */ 7213*37da2899SCharles.Forsyth DO_SDS 7214*37da2899SCharles.Forsyth break; 7215*37da2899SCharles.Forsyth 7216*37da2899SCharles.Forsyth case 0x60: /* ADD */ 7217*37da2899SCharles.Forsyth DO_ADD 7218*37da2899SCharles.Forsyth break; 7219*37da2899SCharles.Forsyth 7220*37da2899SCharles.Forsyth case 0x61: /* SUB */ 7221*37da2899SCharles.Forsyth DO_SUB 7222*37da2899SCharles.Forsyth break; 7223*37da2899SCharles.Forsyth 7224*37da2899SCharles.Forsyth case 0x62: /* DIV */ 7225*37da2899SCharles.Forsyth DO_DIV 7226*37da2899SCharles.Forsyth break; 7227*37da2899SCharles.Forsyth 7228*37da2899SCharles.Forsyth case 0x63: /* MUL */ 7229*37da2899SCharles.Forsyth DO_MUL 7230*37da2899SCharles.Forsyth break; 7231*37da2899SCharles.Forsyth 7232*37da2899SCharles.Forsyth case 0x64: /* ABS */ 7233*37da2899SCharles.Forsyth DO_ABS 7234*37da2899SCharles.Forsyth break; 7235*37da2899SCharles.Forsyth 7236*37da2899SCharles.Forsyth case 0x65: /* NEG */ 7237*37da2899SCharles.Forsyth DO_NEG 7238*37da2899SCharles.Forsyth break; 7239*37da2899SCharles.Forsyth 7240*37da2899SCharles.Forsyth case 0x66: /* FLOOR */ 7241*37da2899SCharles.Forsyth DO_FLOOR 7242*37da2899SCharles.Forsyth break; 7243*37da2899SCharles.Forsyth 7244*37da2899SCharles.Forsyth case 0x67: /* CEILING */ 7245*37da2899SCharles.Forsyth DO_CEILING 7246*37da2899SCharles.Forsyth break; 7247*37da2899SCharles.Forsyth 7248*37da2899SCharles.Forsyth case 0x68: /* ROUND */ 7249*37da2899SCharles.Forsyth case 0x69: /* ROUND */ 7250*37da2899SCharles.Forsyth case 0x6A: /* ROUND */ 7251*37da2899SCharles.Forsyth case 0x6B: /* ROUND */ 7252*37da2899SCharles.Forsyth DO_ROUND 7253*37da2899SCharles.Forsyth break; 7254*37da2899SCharles.Forsyth 7255*37da2899SCharles.Forsyth case 0x6C: /* NROUND */ 7256*37da2899SCharles.Forsyth case 0x6D: /* NROUND */ 7257*37da2899SCharles.Forsyth case 0x6E: /* NRRUND */ 7258*37da2899SCharles.Forsyth case 0x6F: /* NROUND */ 7259*37da2899SCharles.Forsyth DO_NROUND 7260*37da2899SCharles.Forsyth break; 7261*37da2899SCharles.Forsyth 7262*37da2899SCharles.Forsyth case 0x70: /* WCVTF */ 7263*37da2899SCharles.Forsyth DO_WCVTF 7264*37da2899SCharles.Forsyth break; 7265*37da2899SCharles.Forsyth 7266*37da2899SCharles.Forsyth case 0x71: /* DELTAP2 */ 7267*37da2899SCharles.Forsyth case 0x72: /* DELTAP3 */ 7268*37da2899SCharles.Forsyth Ins_DELTAP( EXEC_ARG_ args ); 7269*37da2899SCharles.Forsyth break; 7270*37da2899SCharles.Forsyth 7271*37da2899SCharles.Forsyth case 0x73: /* DELTAC0 */ 7272*37da2899SCharles.Forsyth case 0x74: /* DELTAC1 */ 7273*37da2899SCharles.Forsyth case 0x75: /* DELTAC2 */ 7274*37da2899SCharles.Forsyth Ins_DELTAC( EXEC_ARG_ args ); 7275*37da2899SCharles.Forsyth break; 7276*37da2899SCharles.Forsyth 7277*37da2899SCharles.Forsyth case 0x76: /* SROUND */ 7278*37da2899SCharles.Forsyth DO_SROUND 7279*37da2899SCharles.Forsyth break; 7280*37da2899SCharles.Forsyth 7281*37da2899SCharles.Forsyth case 0x77: /* S45Round */ 7282*37da2899SCharles.Forsyth DO_S45ROUND 7283*37da2899SCharles.Forsyth break; 7284*37da2899SCharles.Forsyth 7285*37da2899SCharles.Forsyth case 0x78: /* JROT */ 7286*37da2899SCharles.Forsyth DO_JROT 7287*37da2899SCharles.Forsyth break; 7288*37da2899SCharles.Forsyth 7289*37da2899SCharles.Forsyth case 0x79: /* JROF */ 7290*37da2899SCharles.Forsyth DO_JROF 7291*37da2899SCharles.Forsyth break; 7292*37da2899SCharles.Forsyth 7293*37da2899SCharles.Forsyth case 0x7A: /* ROFF */ 7294*37da2899SCharles.Forsyth DO_ROFF 7295*37da2899SCharles.Forsyth break; 7296*37da2899SCharles.Forsyth 7297*37da2899SCharles.Forsyth case 0x7B: /* ???? */ 7298*37da2899SCharles.Forsyth Ins_UNKNOWN( EXEC_ARG_ args ); 7299*37da2899SCharles.Forsyth break; 7300*37da2899SCharles.Forsyth 7301*37da2899SCharles.Forsyth case 0x7C: /* RUTG */ 7302*37da2899SCharles.Forsyth DO_RUTG 7303*37da2899SCharles.Forsyth break; 7304*37da2899SCharles.Forsyth 7305*37da2899SCharles.Forsyth case 0x7D: /* RDTG */ 7306*37da2899SCharles.Forsyth DO_RDTG 7307*37da2899SCharles.Forsyth break; 7308*37da2899SCharles.Forsyth 7309*37da2899SCharles.Forsyth case 0x7E: /* SANGW */ 7310*37da2899SCharles.Forsyth case 0x7F: /* AA */ 7311*37da2899SCharles.Forsyth /* nothing - obsolete */ 7312*37da2899SCharles.Forsyth break; 7313*37da2899SCharles.Forsyth 7314*37da2899SCharles.Forsyth case 0x80: /* FLIPPT */ 7315*37da2899SCharles.Forsyth Ins_FLIPPT( EXEC_ARG_ args ); 7316*37da2899SCharles.Forsyth break; 7317*37da2899SCharles.Forsyth 7318*37da2899SCharles.Forsyth case 0x81: /* FLIPRGON */ 7319*37da2899SCharles.Forsyth Ins_FLIPRGON( EXEC_ARG_ args ); 7320*37da2899SCharles.Forsyth break; 7321*37da2899SCharles.Forsyth 7322*37da2899SCharles.Forsyth case 0x82: /* FLIPRGOFF */ 7323*37da2899SCharles.Forsyth Ins_FLIPRGOFF( EXEC_ARG_ args ); 7324*37da2899SCharles.Forsyth break; 7325*37da2899SCharles.Forsyth 7326*37da2899SCharles.Forsyth case 0x83: /* UNKNOWN */ 7327*37da2899SCharles.Forsyth case 0x84: /* UNKNOWN */ 7328*37da2899SCharles.Forsyth Ins_UNKNOWN( EXEC_ARG_ args ); 7329*37da2899SCharles.Forsyth break; 7330*37da2899SCharles.Forsyth 7331*37da2899SCharles.Forsyth case 0x85: /* SCANCTRL */ 7332*37da2899SCharles.Forsyth Ins_SCANCTRL( EXEC_ARG_ args ); 7333*37da2899SCharles.Forsyth break; 7334*37da2899SCharles.Forsyth 7335*37da2899SCharles.Forsyth case 0x86: /* SDPVTL */ 7336*37da2899SCharles.Forsyth case 0x87: /* SDPVTL */ 7337*37da2899SCharles.Forsyth Ins_SDPVTL( EXEC_ARG_ args ); 7338*37da2899SCharles.Forsyth break; 7339*37da2899SCharles.Forsyth 7340*37da2899SCharles.Forsyth case 0x88: /* GETINFO */ 7341*37da2899SCharles.Forsyth Ins_GETINFO( EXEC_ARG_ args ); 7342*37da2899SCharles.Forsyth break; 7343*37da2899SCharles.Forsyth 7344*37da2899SCharles.Forsyth case 0x89: /* IDEF */ 7345*37da2899SCharles.Forsyth Ins_IDEF( EXEC_ARG_ args ); 7346*37da2899SCharles.Forsyth break; 7347*37da2899SCharles.Forsyth 7348*37da2899SCharles.Forsyth case 0x8A: /* ROLL */ 7349*37da2899SCharles.Forsyth Ins_ROLL( EXEC_ARG_ args ); 7350*37da2899SCharles.Forsyth break; 7351*37da2899SCharles.Forsyth 7352*37da2899SCharles.Forsyth case 0x8B: /* MAX */ 7353*37da2899SCharles.Forsyth DO_MAX 7354*37da2899SCharles.Forsyth break; 7355*37da2899SCharles.Forsyth 7356*37da2899SCharles.Forsyth case 0x8C: /* MIN */ 7357*37da2899SCharles.Forsyth DO_MIN 7358*37da2899SCharles.Forsyth break; 7359*37da2899SCharles.Forsyth 7360*37da2899SCharles.Forsyth case 0x8D: /* SCANTYPE */ 7361*37da2899SCharles.Forsyth Ins_SCANTYPE( EXEC_ARG_ args ); 7362*37da2899SCharles.Forsyth break; 7363*37da2899SCharles.Forsyth 7364*37da2899SCharles.Forsyth case 0x8E: /* INSTCTRL */ 7365*37da2899SCharles.Forsyth Ins_INSTCTRL( EXEC_ARG_ args ); 7366*37da2899SCharles.Forsyth break; 7367*37da2899SCharles.Forsyth 7368*37da2899SCharles.Forsyth case 0x8F: 7369*37da2899SCharles.Forsyth Ins_UNKNOWN( EXEC_ARG_ args ); 7370*37da2899SCharles.Forsyth break; 7371*37da2899SCharles.Forsyth 7372*37da2899SCharles.Forsyth default: 7373*37da2899SCharles.Forsyth if ( opcode >= 0xE0 ) 7374*37da2899SCharles.Forsyth Ins_MIRP( EXEC_ARG_ args ); 7375*37da2899SCharles.Forsyth else if ( opcode >= 0xC0 ) 7376*37da2899SCharles.Forsyth Ins_MDRP( EXEC_ARG_ args ); 7377*37da2899SCharles.Forsyth else if ( opcode >= 0xB8 ) 7378*37da2899SCharles.Forsyth Ins_PUSHW( EXEC_ARG_ args ); 7379*37da2899SCharles.Forsyth else if ( opcode >= 0xB0 ) 7380*37da2899SCharles.Forsyth Ins_PUSHB( EXEC_ARG_ args ); 7381*37da2899SCharles.Forsyth else 7382*37da2899SCharles.Forsyth Ins_UNKNOWN( EXEC_ARG_ args ); 7383*37da2899SCharles.Forsyth } 7384*37da2899SCharles.Forsyth 7385*37da2899SCharles.Forsyth } 7386*37da2899SCharles.Forsyth 7387*37da2899SCharles.Forsyth #else 7388*37da2899SCharles.Forsyth 7389*37da2899SCharles.Forsyth Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); 7390*37da2899SCharles.Forsyth 7391*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ 7392*37da2899SCharles.Forsyth 7393*37da2899SCharles.Forsyth if ( CUR.error != TT_Err_Ok ) 7394*37da2899SCharles.Forsyth { 7395*37da2899SCharles.Forsyth switch ( CUR.error ) 7396*37da2899SCharles.Forsyth { 7397*37da2899SCharles.Forsyth case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ 7398*37da2899SCharles.Forsyth { 7399*37da2899SCharles.Forsyth TT_DefRecord* def = CUR.IDefs; 7400*37da2899SCharles.Forsyth TT_DefRecord* limit = def + CUR.numIDefs; 7401*37da2899SCharles.Forsyth 7402*37da2899SCharles.Forsyth 7403*37da2899SCharles.Forsyth for ( ; def < limit; def++ ) 7404*37da2899SCharles.Forsyth { 7405*37da2899SCharles.Forsyth if ( def->active && CUR.opcode == (FT_Byte)def->opc ) 7406*37da2899SCharles.Forsyth { 7407*37da2899SCharles.Forsyth TT_CallRec* callrec; 7408*37da2899SCharles.Forsyth 7409*37da2899SCharles.Forsyth 7410*37da2899SCharles.Forsyth if ( CUR.callTop >= CUR.callSize ) 7411*37da2899SCharles.Forsyth { 7412*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Reference; 7413*37da2899SCharles.Forsyth goto LErrorLabel_; 7414*37da2899SCharles.Forsyth } 7415*37da2899SCharles.Forsyth 7416*37da2899SCharles.Forsyth callrec = &CUR.callStack[CUR.callTop]; 7417*37da2899SCharles.Forsyth 7418*37da2899SCharles.Forsyth callrec->Caller_Range = CUR.curRange; 7419*37da2899SCharles.Forsyth callrec->Caller_IP = CUR.IP + 1; 7420*37da2899SCharles.Forsyth callrec->Cur_Count = 1; 7421*37da2899SCharles.Forsyth callrec->Cur_Restart = def->start; 7422*37da2899SCharles.Forsyth 7423*37da2899SCharles.Forsyth if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) 7424*37da2899SCharles.Forsyth goto LErrorLabel_; 7425*37da2899SCharles.Forsyth 7426*37da2899SCharles.Forsyth goto LSuiteLabel_; 7427*37da2899SCharles.Forsyth } 7428*37da2899SCharles.Forsyth } 7429*37da2899SCharles.Forsyth } 7430*37da2899SCharles.Forsyth 7431*37da2899SCharles.Forsyth CUR.error = TT_Err_Invalid_Opcode; 7432*37da2899SCharles.Forsyth goto LErrorLabel_; 7433*37da2899SCharles.Forsyth 7434*37da2899SCharles.Forsyth #if 0 7435*37da2899SCharles.Forsyth break; /* Unreachable code warning suppression. */ 7436*37da2899SCharles.Forsyth /* Leave to remind in case a later change the editor */ 7437*37da2899SCharles.Forsyth /* to consider break; */ 7438*37da2899SCharles.Forsyth #endif 7439*37da2899SCharles.Forsyth 7440*37da2899SCharles.Forsyth default: 7441*37da2899SCharles.Forsyth goto LErrorLabel_; 7442*37da2899SCharles.Forsyth 7443*37da2899SCharles.Forsyth #if 0 7444*37da2899SCharles.Forsyth break; 7445*37da2899SCharles.Forsyth #endif 7446*37da2899SCharles.Forsyth } 7447*37da2899SCharles.Forsyth } 7448*37da2899SCharles.Forsyth 7449*37da2899SCharles.Forsyth CUR.top = CUR.new_top; 7450*37da2899SCharles.Forsyth 7451*37da2899SCharles.Forsyth if ( CUR.step_ins ) 7452*37da2899SCharles.Forsyth CUR.IP += CUR.length; 7453*37da2899SCharles.Forsyth 7454*37da2899SCharles.Forsyth /* increment instruction counter and check if we didn't */ 7455*37da2899SCharles.Forsyth /* run this program for too long (e.g. infinite loops). */ 7456*37da2899SCharles.Forsyth if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) 7457*37da2899SCharles.Forsyth return TT_Err_Execution_Too_Long; 7458*37da2899SCharles.Forsyth 7459*37da2899SCharles.Forsyth LSuiteLabel_: 7460*37da2899SCharles.Forsyth if ( CUR.IP >= CUR.codeSize ) 7461*37da2899SCharles.Forsyth { 7462*37da2899SCharles.Forsyth if ( CUR.callTop > 0 ) 7463*37da2899SCharles.Forsyth { 7464*37da2899SCharles.Forsyth CUR.error = TT_Err_Code_Overflow; 7465*37da2899SCharles.Forsyth goto LErrorLabel_; 7466*37da2899SCharles.Forsyth } 7467*37da2899SCharles.Forsyth else 7468*37da2899SCharles.Forsyth goto LNo_Error_; 7469*37da2899SCharles.Forsyth } 7470*37da2899SCharles.Forsyth } while ( !CUR.instruction_trap ); 7471*37da2899SCharles.Forsyth 7472*37da2899SCharles.Forsyth LNo_Error_: 7473*37da2899SCharles.Forsyth 7474*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_STATIC_RASTER 7475*37da2899SCharles.Forsyth *exc = cur; 7476*37da2899SCharles.Forsyth #endif 7477*37da2899SCharles.Forsyth 7478*37da2899SCharles.Forsyth return TT_Err_Ok; 7479*37da2899SCharles.Forsyth 7480*37da2899SCharles.Forsyth LErrorCodeOverflow_: 7481*37da2899SCharles.Forsyth CUR.error = TT_Err_Code_Overflow; 7482*37da2899SCharles.Forsyth 7483*37da2899SCharles.Forsyth LErrorLabel_: 7484*37da2899SCharles.Forsyth 7485*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_STATIC_RASTER 7486*37da2899SCharles.Forsyth *exc = cur; 7487*37da2899SCharles.Forsyth #endif 7488*37da2899SCharles.Forsyth 7489*37da2899SCharles.Forsyth return CUR.error; 7490*37da2899SCharles.Forsyth } 7491*37da2899SCharles.Forsyth 7492*37da2899SCharles.Forsyth 7493*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ 7494*37da2899SCharles.Forsyth 7495*37da2899SCharles.Forsyth 7496*37da2899SCharles.Forsyth /* END */ 7497