Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: third_party/freetype/src/truetype/ttinterp.c

Issue 1413673003: Update bundled freetype to 2.6.1 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: DEPS for corpus Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* ttinterp.c */ 3 /* ttinterp.c */
4 /* */ 4 /* */
5 /* TrueType bytecode interpreter (body). */ 5 /* TrueType bytecode interpreter (body). */
6 /* */ 6 /* */
7 /* Copyright 1996-2014 */ 7 /* Copyright 1996-2015 by */
8 /* by David Turner, Robert Wilhelm, and Werner Lemberg. */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */ 9 /* */
10 /* This file is part of the FreeType project, and may only be used, */ 10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */ 11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */ 13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */ 14 /* understand and accept it fully. */
15 /* */ 15 /* */
16 /***************************************************************************/ 16 /***************************************************************************/
17 17
18 18
(...skipping 18 matching lines...) Expand all
37 37
38 /*************************************************************************/ 38 /*************************************************************************/
39 /* */ 39 /* */
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */ 42 /* messages during execution. */
43 /* */ 43 /* */
44 #undef FT_COMPONENT 44 #undef FT_COMPONENT
45 #define FT_COMPONENT trace_ttinterp 45 #define FT_COMPONENT trace_ttinterp
46 46
47
47 /*************************************************************************/ 48 /*************************************************************************/
48 /* */ 49 /* */
49 /* In order to detect infinite loops in the code, we set up a counter */ 50 /* In order to detect infinite loops in the code, we set up a counter */
50 /* within the run loop. A single stroke of interpretation is now */ 51 /* within the run loop. A single stroke of interpretation is now */
51 /* limited to a maximum number of opcodes defined below. */ 52 /* limited to a maximum number of opcodes defined below. */
52 /* */ 53 /* */
53 #define MAX_RUNNABLE_OPCODES 1000000L 54 #define MAX_RUNNABLE_OPCODES 1000000L
54 55
55 56
56 /*************************************************************************/ 57 #define SUBPIXEL_HINTING \
57 /* */ 58 ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
58 /* There are two kinds of implementations: */
59 /* */
60 /* a. static implementation */
61 /* */
62 /* The current execution context is a static variable, which fields */
63 /* are accessed directly by the interpreter during execution. The */
64 /* context is named `cur'. */
65 /* */
66 /* This version is non-reentrant, of course. */
67 /* */
68 /* b. indirect implementation */
69 /* */
70 /* The current execution context is passed to _each_ function as its */
71 /* first argument, and each field is thus accessed indirectly. */
72 /* */
73 /* This version is fully re-entrant. */
74 /* */
75 /* The idea is that an indirect implementation may be slower to execute */
76 /* on low-end processors that are used in some systems (like 386s or */
77 /* even 486s). */
78 /* */
79 /* As a consequence, the indirect implementation is now the default, as */
80 /* its performance costs can be considered negligible in our context. */
81 /* Note, however, that we kept the same source with macros because: */
82 /* */
83 /* - The code is kept very close in design to the Pascal code used for */
84 /* development. */
85 /* */
86 /* - It's much more readable that way! */
87 /* */
88 /* - It's still open to experimentation and tuning. */
89 /* */
90 /*************************************************************************/
91
92
93 #ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
94
95 #define CUR (*exc) /* see ttobjs.h */
96
97 /*************************************************************************/
98 /* */
99 /* This macro is used whenever `exec' is unused in a function, to avoid */
100 /* stupid warnings from pedantic compilers. */
101 /* */
102 #define FT_UNUSED_EXEC FT_UNUSED( exc )
103
104 #else /* static implementation */
105
106 #define CUR cur
107
108 #define FT_UNUSED_EXEC int __dummy = __dummy
109
110 static
111 TT_ExecContextRec cur; /* static exec. context variable */
112
113 /* apparently, we have a _lot_ of direct indexing when accessing */
114 /* the static `cur', which makes the code bigger (due to all the */
115 /* four bytes addresses). */
116
117 #endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
118
119
120 /*************************************************************************/
121 /* */
122 /* The instruction argument stack. */
123 /* */
124 #define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */
125
126
127 /*************************************************************************/
128 /* */
129 /* This macro is used whenever `args' is unused in a function, to avoid */
130 /* stupid warnings from pedantic compilers. */
131 /* */
132 #define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args )
133
134
135 #define SUBPIXEL_HINTING \
136 ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
137 TT_INTERPRETER_VERSION_38 ) 59 TT_INTERPRETER_VERSION_38 )
138 60
139 61
140 /*************************************************************************/ 62 #define PROJECT( v1, v2 ) \
141 /* */ 63 exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
142 /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */
143 /* increase readability of the code. */
144 /* */
145 /*************************************************************************/
146 64
65 #define DUALPROJ( v1, v2 ) \
66 exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
147 67
148 #define SKIP_Code() \ 68 #define FAST_PROJECT( v ) \
149 SkipCode( EXEC_ARG ) 69 exc->func_project( exc, (v)->x, (v)->y )
150 70
151 #define GET_ShortIns() \ 71 #define FAST_DUALPROJ( v ) \
152 GetShortIns( EXEC_ARG ) 72 exc->func_dualproj( exc, (v)->x, (v)->y )
153
154 #define NORMalize( x, y, v ) \
155 Normalize( EXEC_ARG_ x, y, v )
156
157 #define SET_SuperRound( scale, flags ) \
158 SetSuperRound( EXEC_ARG_ scale, flags )
159
160 #define ROUND_None( d, c ) \
161 Round_None( EXEC_ARG_ d, c )
162
163 #define INS_Goto_CodeRange( range, ip ) \
164 Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
165
166 #define CUR_Func_move( z, p, d ) \
167 CUR.func_move( EXEC_ARG_ z, p, d )
168
169 #define CUR_Func_move_orig( z, p, d ) \
170 CUR.func_move_orig( EXEC_ARG_ z, p, d )
171
172 #define CUR_Func_round( d, c ) \
173 CUR.func_round( EXEC_ARG_ d, c )
174
175 #define CUR_Func_cur_ppem() \
176 CUR.func_cur_ppem( EXEC_ARG )
177
178 #define CUR_Func_read_cvt( index ) \
179 CUR.func_read_cvt( EXEC_ARG_ index )
180
181 #define CUR_Func_write_cvt( index, val ) \
182 CUR.func_write_cvt( EXEC_ARG_ index, val )
183
184 #define CUR_Func_move_cvt( index, val ) \
185 CUR.func_move_cvt( EXEC_ARG_ index, val )
186
187 #define CURRENT_Ratio() \
188 Current_Ratio( EXEC_ARG )
189
190 #define INS_SxVTL( a, b, c, d ) \
191 Ins_SxVTL( EXEC_ARG_ a, b, c, d )
192
193 #define COMPUTE_Funcs() \
194 Compute_Funcs( EXEC_ARG )
195
196 #define COMPUTE_Round( a ) \
197 Compute_Round( EXEC_ARG_ a )
198
199 #define COMPUTE_Point_Displacement( a, b, c, d ) \
200 Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
201
202 #define MOVE_Zp2_Point( a, b, c, t ) \
203 Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
204
205
206 #define CUR_Func_project( v1, v2 ) \
207 CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
208
209 #define CUR_Func_dualproj( v1, v2 ) \
210 CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
211
212 #define CUR_fast_project( v ) \
213 CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
214
215 #define CUR_fast_dualproj( v ) \
216 CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
217 73
218 74
219 /*************************************************************************/ 75 /*************************************************************************/
220 /* */ 76 /* */
221 /* Instruction dispatch function, as used by the interpreter. */ 77 /* Instruction dispatch function, as used by the interpreter. */
222 /* */ 78 /* */
223 typedef void (*TInstruction_Function)( INS_ARG ); 79 typedef void (*TInstruction_Function)( TT_ExecContext exc,
80 FT_Long* args );
224 81
225 82
226 /*************************************************************************/ 83 /*************************************************************************/
227 /* */ 84 /* */
228 /* Two simple bounds-checking macros. */ 85 /* Two simple bounds-checking macros. */
229 /* */ 86 /* */
230 #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) 87 #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
231 #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) 88 #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) )
232 89
233 /*************************************************************************/
234 /* */
235 /* This macro computes (a*2^14)/b and complements TT_MulFix14. */
236 /* */
237 #define TT_DivFix14( a, b ) \
238 FT_DivFix( a, (b) << 2 )
239
240 90
241 #undef SUCCESS 91 #undef SUCCESS
242 #define SUCCESS 0 92 #define SUCCESS 0
243 93
244 #undef FAILURE 94 #undef FAILURE
245 #define FAILURE 1 95 #define FAILURE 1
246 96
247 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 97 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
248 #define GUESS_VECTOR( V ) \ 98 #define GUESS_VECTOR( V ) \
249 if ( CUR.face->unpatented_hinting ) \ 99 do \
250 { \ 100 { \
251 CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ 101 if ( exc->face->unpatented_hinting ) \
252 CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ 102 { \
253 } 103 exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
104 exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
105 } \
106 } while (0)
254 #else 107 #else
255 #define GUESS_VECTOR( V ) 108 #define GUESS_VECTOR( V ) do { } while (0)
256 #endif 109 #endif
257 110
111
258 /*************************************************************************/ 112 /*************************************************************************/
259 /* */ 113 /* */
260 /* CODERANGE FUNCTIONS */ 114 /* CODERANGE FUNCTIONS */
261 /* */ 115 /* */
262 /*************************************************************************/ 116 /*************************************************************************/
263 117
264 118
265 /*************************************************************************/ 119 /*************************************************************************/
266 /* */ 120 /* */
267 /* <Function> */ 121 /* <Function> */
(...skipping 22 matching lines...) Expand all
290 FT_ASSERT( range >= 1 && range <= 3 ); 144 FT_ASSERT( range >= 1 && range <= 3 );
291 145
292 coderange = &exec->codeRangeTable[range - 1]; 146 coderange = &exec->codeRangeTable[range - 1];
293 147
294 FT_ASSERT( coderange->base != NULL ); 148 FT_ASSERT( coderange->base != NULL );
295 149
296 /* NOTE: Because the last instruction of a program may be a CALL */ 150 /* NOTE: Because the last instruction of a program may be a CALL */
297 /* which will return to the first byte *after* the code */ 151 /* which will return to the first byte *after* the code */
298 /* range, we test for IP <= Size instead of IP < Size. */ 152 /* range, we test for IP <= Size instead of IP < Size. */
299 /* */ 153 /* */
300 FT_ASSERT( (FT_ULong)IP <= coderange->size ); 154 FT_ASSERT( IP <= coderange->size );
301 155
302 exec->code = coderange->base; 156 exec->code = coderange->base;
303 exec->codeSize = coderange->size; 157 exec->codeSize = coderange->size;
304 exec->IP = IP; 158 exec->IP = IP;
305 exec->curRange = range; 159 exec->curRange = range;
306 } 160 }
307 161
308 162
309 /*************************************************************************/ 163 /*************************************************************************/
310 /* */ 164 /* */
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 /* in elements. */ 345 /* in elements. */
492 /* */ 346 /* */
493 /* buff :: The address of the buffer base pointer. */ 347 /* buff :: The address of the buffer base pointer. */
494 /* */ 348 /* */
495 /* <Return> */ 349 /* <Return> */
496 /* FreeType error code. 0 means success. */ 350 /* FreeType error code. 0 means success. */
497 /* */ 351 /* */
498 FT_LOCAL_DEF( FT_Error ) 352 FT_LOCAL_DEF( FT_Error )
499 Update_Max( FT_Memory memory, 353 Update_Max( FT_Memory memory,
500 FT_ULong* size, 354 FT_ULong* size,
501 FT_Long multiplier, 355 FT_ULong multiplier,
502 void* _pbuff, 356 void* _pbuff,
503 FT_ULong new_max ) 357 FT_ULong new_max )
504 { 358 {
505 FT_Error error; 359 FT_Error error;
506 void** pbuff = (void**)_pbuff; 360 void** pbuff = (void**)_pbuff;
507 361
508 362
509 if ( *size < new_max ) 363 if ( *size < new_max )
510 { 364 {
511 if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) 365 if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 438
585 /* In case of multi-threading it can happen that the old size object */ 439 /* In case of multi-threading it can happen that the old size object */
586 /* no longer exists, thus we must clear all glyph zone references. */ 440 /* no longer exists, thus we must clear all glyph zone references. */
587 ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); 441 ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) );
588 exec->zp1 = exec->zp0; 442 exec->zp1 = exec->zp0;
589 exec->zp2 = exec->zp0; 443 exec->zp2 = exec->zp0;
590 } 444 }
591 445
592 /* XXX: We reserve a little more elements on the stack to deal safely */ 446 /* XXX: We reserve a little more elements on the stack to deal safely */
593 /* with broken fonts like arialbs, courbs, timesbs, etc. */ 447 /* with broken fonts like arialbs, courbs, timesbs, etc. */
594 tmp = exec->stackSize; 448 tmp = (FT_ULong)exec->stackSize;
595 error = Update_Max( exec->memory, 449 error = Update_Max( exec->memory,
596 &tmp, 450 &tmp,
597 sizeof ( FT_F26Dot6 ), 451 sizeof ( FT_F26Dot6 ),
598 (void*)&exec->stack, 452 (void*)&exec->stack,
599 maxp->maxStackElements + 32 ); 453 maxp->maxStackElements + 32 );
600 exec->stackSize = (FT_UInt)tmp; 454 exec->stackSize = (FT_Long)tmp;
601 if ( error ) 455 if ( error )
602 return error; 456 return error;
603 457
604 tmp = exec->glyphSize; 458 tmp = exec->glyphSize;
605 error = Update_Max( exec->memory, 459 error = Update_Max( exec->memory,
606 &tmp, 460 &tmp,
607 sizeof ( FT_Byte ), 461 sizeof ( FT_Byte ),
608 (void*)&exec->glyphIns, 462 (void*)&exec->glyphIns,
609 maxp->maxSizeOfInstructions ); 463 maxp->maxSizeOfInstructions );
610 exec->glyphSize = (FT_UShort)tmp; 464 exec->glyphSize = (FT_UShort)tmp;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 /* is called. */ 530 /* is called. */
677 /* */ 531 /* */
678 /* This is commented out currently. */ 532 /* This is commented out currently. */
679 /* */ 533 /* */
680 /* <Input> */ 534 /* <Input> */
681 /* exec :: A handle to the target execution context. */ 535 /* exec :: A handle to the target execution context. */
682 /* */ 536 /* */
683 /* <Return> */ 537 /* <Return> */
684 /* TrueType error code. 0 means success. */ 538 /* TrueType error code. 0 means success. */
685 /* */ 539 /* */
686 /* <Note> */
687 /* Only the glyph loader and debugger should call this function. */
688 /* */
689 FT_LOCAL_DEF( FT_Error ) 540 FT_LOCAL_DEF( FT_Error )
690 TT_Run_Context( TT_ExecContext exec, 541 TT_Run_Context( TT_ExecContext exec )
691 FT_Bool debug )
692 { 542 {
693 TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ); 543 TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
694 544
695 exec->zp0 = exec->pts; 545 exec->zp0 = exec->pts;
696 exec->zp1 = exec->pts; 546 exec->zp1 = exec->pts;
697 exec->zp2 = exec->pts; 547 exec->zp2 = exec->pts;
698 548
699 exec->GS.gep0 = 1; 549 exec->GS.gep0 = 1;
700 exec->GS.gep1 = 1; 550 exec->GS.gep1 = 1;
701 exec->GS.gep2 = 1; 551 exec->GS.gep2 = 1;
702 552
703 exec->GS.projVector.x = 0x4000; 553 exec->GS.projVector.x = 0x4000;
704 exec->GS.projVector.y = 0x0000; 554 exec->GS.projVector.y = 0x0000;
705 555
706 exec->GS.freeVector = exec->GS.projVector; 556 exec->GS.freeVector = exec->GS.projVector;
707 exec->GS.dualVector = exec->GS.projVector; 557 exec->GS.dualVector = exec->GS.projVector;
708 558
709 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 559 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
710 exec->GS.both_x_axis = TRUE; 560 exec->GS.both_x_axis = TRUE;
711 #endif 561 #endif
712 562
713 exec->GS.round_state = 1; 563 exec->GS.round_state = 1;
714 exec->GS.loop = 1; 564 exec->GS.loop = 1;
715 565
716 /* some glyphs leave something on the stack. so we clean it */ 566 /* some glyphs leave something on the stack. so we clean it */
717 /* before a new execution. */ 567 /* before a new execution. */
718 exec->top = 0; 568 exec->top = 0;
719 exec->callTop = 0; 569 exec->callTop = 0;
720 570
721 #if 1
722 FT_UNUSED( debug );
723
724 return exec->face->interpreter( exec ); 571 return exec->face->interpreter( exec );
725 #else
726 if ( !debug )
727 return TT_RunIns( exec );
728 else
729 return FT_Err_Ok;
730 #endif
731 } 572 }
732 573
733 574
734 /* The default value for `scan_control' is documented as FALSE in the */ 575 /* The default value for `scan_control' is documented as FALSE in the */
735 /* TrueType specification. This is confusing since it implies a */ 576 /* TrueType specification. This is confusing since it implies a */
736 /* Boolean value. However, this is not the case, thus both the */ 577 /* Boolean value. However, this is not the case, thus both the */
737 /* default values of our `scan_type' and `scan_control' fields (which */ 578 /* default values of our `scan_type' and `scan_control' fields (which */
738 /* the documentation's `scan_control' variable is split into) are */ 579 /* the documentation's `scan_control' variable is split into) are */
739 /* zero. */ 580 /* zero. */
740 581
(...skipping 13 matching lines...) Expand all
754 0, FALSE, 0, 1, 1, 1 595 0, FALSE, 0, 1, 1, 1
755 }; 596 };
756 597
757 598
758 /* documentation is in ttinterp.h */ 599 /* documentation is in ttinterp.h */
759 600
760 FT_EXPORT_DEF( TT_ExecContext ) 601 FT_EXPORT_DEF( TT_ExecContext )
761 TT_New_Context( TT_Driver driver ) 602 TT_New_Context( TT_Driver driver )
762 { 603 {
763 FT_Memory memory; 604 FT_Memory memory;
605 FT_Error error;
606
607 TT_ExecContext exec = NULL;
764 608
765 609
766 if ( !driver ) 610 if ( !driver )
767 goto Fail; 611 goto Fail;
768 612
769 memory = driver->root.root.memory; 613 memory = driver->root.root.memory;
770 614
771 if ( !driver->context ) 615 /* allocate object */
772 { 616 if ( FT_NEW( exec ) )
773 FT_Error error; 617 goto Fail;
774 TT_ExecContext exec;
775 618
619 /* initialize it; in case of error this deallocates `exec' too */
620 error = Init_Context( exec, memory );
621 if ( error )
622 goto Fail;
776 623
777 /* allocate object */ 624 return exec;
778 if ( FT_NEW( exec ) )
779 goto Fail;
780
781 /* initialize it; in case of error this deallocates `exec' too */
782 error = Init_Context( exec, memory );
783 if ( error )
784 goto Fail;
785
786 /* store it into the driver */
787 driver->context = exec;
788 }
789
790 return driver->context;
791 625
792 Fail: 626 Fail:
793 return NULL; 627 return NULL;
794 } 628 }
795 629
796 630
797 /*************************************************************************/ 631 /*************************************************************************/
798 /* */ 632 /* */
799 /* Before an opcode is executed, the interpreter verifies that there are */ 633 /* Before an opcode is executed, the interpreter verifies that there are */
800 /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ 634 /* enough arguments on the stack, with the help of the `Pop_Push_Count' */
(...skipping 26 matching lines...) Expand all
827 /* SPvTCA y */ PACK( 0, 0 ), 661 /* SPvTCA y */ PACK( 0, 0 ),
828 /* SPvTCA x */ PACK( 0, 0 ), 662 /* SPvTCA x */ PACK( 0, 0 ),
829 /* SFvTCA y */ PACK( 0, 0 ), 663 /* SFvTCA y */ PACK( 0, 0 ),
830 /* SFvTCA x */ PACK( 0, 0 ), 664 /* SFvTCA x */ PACK( 0, 0 ),
831 /* SPvTL // */ PACK( 2, 0 ), 665 /* SPvTL // */ PACK( 2, 0 ),
832 /* SPvTL + */ PACK( 2, 0 ), 666 /* SPvTL + */ PACK( 2, 0 ),
833 /* SFvTL // */ PACK( 2, 0 ), 667 /* SFvTL // */ PACK( 2, 0 ),
834 /* SFvTL + */ PACK( 2, 0 ), 668 /* SFvTL + */ PACK( 2, 0 ),
835 /* SPvFS */ PACK( 2, 0 ), 669 /* SPvFS */ PACK( 2, 0 ),
836 /* SFvFS */ PACK( 2, 0 ), 670 /* SFvFS */ PACK( 2, 0 ),
837 /* GPV */ PACK( 0, 2 ), 671 /* GPv */ PACK( 0, 2 ),
838 /* GFV */ PACK( 0, 2 ), 672 /* GFv */ PACK( 0, 2 ),
839 /* SFvTPv */ PACK( 0, 0 ), 673 /* SFvTPv */ PACK( 0, 0 ),
840 /* ISECT */ PACK( 5, 0 ), 674 /* ISECT */ PACK( 5, 0 ),
841 675
842 /* SRP0 */ PACK( 1, 0 ), 676 /* SRP0 */ PACK( 1, 0 ),
843 /* SRP1 */ PACK( 1, 0 ), 677 /* SRP1 */ PACK( 1, 0 ),
844 /* SRP2 */ PACK( 1, 0 ), 678 /* SRP2 */ PACK( 1, 0 ),
845 /* SZP0 */ PACK( 1, 0 ), 679 /* SZP0 */ PACK( 1, 0 ),
846 /* SZP1 */ PACK( 1, 0 ), 680 /* SZP1 */ PACK( 1, 0 ),
847 /* SZP2 */ PACK( 1, 0 ), 681 /* SZP2 */ PACK( 1, 0 ),
848 /* SZPS */ PACK( 1, 0 ), 682 /* SZPS */ PACK( 1, 0 ),
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 /* RDTG */ PACK( 0, 0 ), 791 /* RDTG */ PACK( 0, 0 ),
958 /* SANGW */ PACK( 1, 0 ), 792 /* SANGW */ PACK( 1, 0 ),
959 /* AA */ PACK( 1, 0 ), 793 /* AA */ PACK( 1, 0 ),
960 794
961 /* FlipPT */ PACK( 0, 0 ), 795 /* FlipPT */ PACK( 0, 0 ),
962 /* FlipRgON */ PACK( 2, 0 ), 796 /* FlipRgON */ PACK( 2, 0 ),
963 /* FlipRgOFF */ PACK( 2, 0 ), 797 /* FlipRgOFF */ PACK( 2, 0 ),
964 /* INS_$83 */ PACK( 0, 0 ), 798 /* INS_$83 */ PACK( 0, 0 ),
965 /* INS_$84 */ PACK( 0, 0 ), 799 /* INS_$84 */ PACK( 0, 0 ),
966 /* ScanCTRL */ PACK( 1, 0 ), 800 /* ScanCTRL */ PACK( 1, 0 ),
967 /* SDPVTL[0] */ PACK( 2, 0 ), 801 /* SDPvTL[0] */ PACK( 2, 0 ),
968 /* SDPVTL[1] */ PACK( 2, 0 ), 802 /* SDPvTL[1] */ PACK( 2, 0 ),
969 /* GetINFO */ PACK( 1, 1 ), 803 /* GetINFO */ PACK( 1, 1 ),
970 /* IDEF */ PACK( 1, 0 ), 804 /* IDEF */ PACK( 1, 0 ),
971 /* ROLL */ PACK( 3, 3 ), 805 /* ROLL */ PACK( 3, 3 ),
972 /* MAX */ PACK( 2, 1 ), 806 /* MAX */ PACK( 2, 1 ),
973 /* MIN */ PACK( 2, 1 ), 807 /* MIN */ PACK( 2, 1 ),
974 /* ScanTYPE */ PACK( 1, 0 ), 808 /* ScanTYPE */ PACK( 1, 0 ),
975 /* InstCTRL */ PACK( 2, 0 ), 809 /* InstCTRL */ PACK( 2, 0 ),
976 /* INS_$8F */ PACK( 0, 0 ), 810 /* INS_$8F */ PACK( 0, 0 ),
977 811
978 /* INS_$90 */ PACK( 0, 0 ), 812 /* INS_$90 */ PACK( 0, 0 ),
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 /* MIRP[27] */ PACK( 2, 0 ), 925 /* MIRP[27] */ PACK( 2, 0 ),
1092 /* MIRP[28] */ PACK( 2, 0 ), 926 /* MIRP[28] */ PACK( 2, 0 ),
1093 /* MIRP[29] */ PACK( 2, 0 ), 927 /* MIRP[29] */ PACK( 2, 0 ),
1094 /* MIRP[30] */ PACK( 2, 0 ), 928 /* MIRP[30] */ PACK( 2, 0 ),
1095 /* MIRP[31] */ PACK( 2, 0 ) 929 /* MIRP[31] */ PACK( 2, 0 )
1096 }; 930 };
1097 931
1098 932
1099 #ifdef FT_DEBUG_LEVEL_TRACE 933 #ifdef FT_DEBUG_LEVEL_TRACE
1100 934
935 /* the first hex digit gives the length of the opcode name; the space */
936 /* after the digit is here just to increase readability of the source */
937 /* code */
938
1101 static 939 static
1102 const char* const opcode_name[256] = 940 const char* const opcode_name[256] =
1103 { 941 {
1104 "SVTCA y", 942 "7 SVTCA y",
1105 "SVTCA x", 943 "7 SVTCA x",
1106 "SPvTCA y", 944 "8 SPvTCA y",
1107 "SPvTCA x", 945 "8 SPvTCA x",
1108 "SFvTCA y", 946 "8 SFvTCA y",
1109 "SFvTCA x", 947 "8 SFvTCA x",
1110 "SPvTL ||", 948 "8 SPvTL ||",
1111 "SPvTL +", 949 "7 SPvTL +",
1112 "SFvTL ||", 950 "8 SFvTL ||",
1113 "SFvTL +", 951 "7 SFvTL +",
1114 "SPvFS", 952 "5 SPvFS",
1115 "SFvFS", 953 "5 SFvFS",
1116 "GPV", 954 "3 GPv",
1117 "GFV", 955 "3 GFv",
1118 "SFvTPv", 956 "6 SFvTPv",
1119 "ISECT", 957 "5 ISECT",
1120 958
1121 "SRP0", 959 "4 SRP0",
1122 "SRP1", 960 "4 SRP1",
1123 "SRP2", 961 "4 SRP2",
1124 "SZP0", 962 "4 SZP0",
1125 "SZP1", 963 "4 SZP1",
1126 "SZP2", 964 "4 SZP2",
1127 "SZPS", 965 "4 SZPS",
1128 "SLOOP", 966 "5 SLOOP",
1129 "RTG", 967 "3 RTG",
1130 "RTHG", 968 "4 RTHG",
1131 "SMD", 969 "3 SMD",
1132 "ELSE", 970 "4 ELSE",
1133 "JMPR", 971 "4 JMPR",
1134 "SCvTCi", 972 "6 SCvTCi",
1135 "SSwCi", 973 "5 SSwCi",
1136 "SSW", 974 "3 SSW",
1137 975
1138 "DUP", 976 "3 DUP",
1139 "POP", 977 "3 POP",
1140 "CLEAR", 978 "5 CLEAR",
1141 "SWAP", 979 "4 SWAP",
1142 "DEPTH", 980 "5 DEPTH",
1143 "CINDEX", 981 "6 CINDEX",
1144 "MINDEX", 982 "6 MINDEX",
1145 "AlignPTS", 983 "8 AlignPTS",
1146 "INS_$28", 984 "7 INS_$28",
1147 "UTP", 985 "3 UTP",
1148 "LOOPCALL", 986 "8 LOOPCALL",
1149 "CALL", 987 "4 CALL",
1150 "FDEF", 988 "4 FDEF",
1151 "ENDF", 989 "4 ENDF",
1152 "MDAP[0]", 990 "7 MDAP[0]",
1153 "MDAP[1]", 991 "7 MDAP[1]",
1154 992
1155 "IUP[0]", 993 "6 IUP[0]",
1156 "IUP[1]", 994 "6 IUP[1]",
1157 "SHP[0]", 995 "6 SHP[0]",
1158 "SHP[1]", 996 "6 SHP[1]",
1159 "SHC[0]", 997 "6 SHC[0]",
1160 "SHC[1]", 998 "6 SHC[1]",
1161 "SHZ[0]", 999 "6 SHZ[0]",
1162 "SHZ[1]", 1000 "6 SHZ[1]",
1163 "SHPIX", 1001 "5 SHPIX",
1164 "IP", 1002 "2 IP",
1165 "MSIRP[0]", 1003 "8 MSIRP[0]",
1166 "MSIRP[1]", 1004 "8 MSIRP[1]",
1167 "AlignRP", 1005 "7 AlignRP",
1168 "RTDG", 1006 "4 RTDG",
1169 "MIAP[0]", 1007 "7 MIAP[0]",
1170 "MIAP[1]", 1008 "7 MIAP[1]",
1171 1009
1172 "NPushB", 1010 "6 NPushB",
1173 "NPushW", 1011 "6 NPushW",
1174 "WS", 1012 "2 WS",
1175 "RS", 1013 "2 RS",
1176 "WCvtP", 1014 "5 WCvtP",
1177 "RCvt", 1015 "4 RCvt",
1178 "GC[0]", 1016 "5 GC[0]",
1179 "GC[1]", 1017 "5 GC[1]",
1180 "SCFS", 1018 "4 SCFS",
1181 "MD[0]", 1019 "5 MD[0]",
1182 "MD[1]", 1020 "5 MD[1]",
1183 "MPPEM", 1021 "5 MPPEM",
1184 "MPS", 1022 "3 MPS",
1185 "FlipON", 1023 "6 FlipON",
1186 "FlipOFF", 1024 "7 FlipOFF",
1187 "DEBUG", 1025 "5 DEBUG",
1188 1026
1189 "LT", 1027 "2 LT",
1190 "LTEQ", 1028 "4 LTEQ",
1191 "GT", 1029 "2 GT",
1192 "GTEQ", 1030 "4 GTEQ",
1193 "EQ", 1031 "2 EQ",
1194 "NEQ", 1032 "3 NEQ",
1195 "ODD", 1033 "3 ODD",
1196 "EVEN", 1034 "4 EVEN",
1197 "IF", 1035 "2 IF",
1198 "EIF", 1036 "3 EIF",
1199 "AND", 1037 "3 AND",
1200 "OR", 1038 "2 OR",
1201 "NOT", 1039 "3 NOT",
1202 "DeltaP1", 1040 "7 DeltaP1",
1203 "SDB", 1041 "3 SDB",
1204 "SDS", 1042 "3 SDS",
1205 1043
1206 "ADD", 1044 "3 ADD",
1207 "SUB", 1045 "3 SUB",
1208 "DIV", 1046 "3 DIV",
1209 "MUL", 1047 "3 MUL",
1210 "ABS", 1048 "3 ABS",
1211 "NEG", 1049 "3 NEG",
1212 "FLOOR", 1050 "5 FLOOR",
1213 "CEILING", 1051 "7 CEILING",
1214 "ROUND[0]", 1052 "8 ROUND[0]",
1215 "ROUND[1]", 1053 "8 ROUND[1]",
1216 "ROUND[2]", 1054 "8 ROUND[2]",
1217 "ROUND[3]", 1055 "8 ROUND[3]",
1218 "NROUND[0]", 1056 "9 NROUND[0]",
1219 "NROUND[1]", 1057 "9 NROUND[1]",
1220 "NROUND[2]", 1058 "9 NROUND[2]",
1221 "NROUND[3]", 1059 "9 NROUND[3]",
1222 1060
1223 "WCvtF", 1061 "5 WCvtF",
1224 "DeltaP2", 1062 "7 DeltaP2",
1225 "DeltaP3", 1063 "7 DeltaP3",
1226 "DeltaCn[0]", 1064 "A DeltaCn[0]",
1227 "DeltaCn[1]", 1065 "A DeltaCn[1]",
1228 "DeltaCn[2]", 1066 "A DeltaCn[2]",
1229 "SROUND", 1067 "6 SROUND",
1230 "S45Round", 1068 "8 S45Round",
1231 "JROT", 1069 "4 JROT",
1232 "JROF", 1070 "4 JROF",
1233 "ROFF", 1071 "4 ROFF",
1234 "INS_$7B", 1072 "7 INS_$7B",
1235 "RUTG", 1073 "4 RUTG",
1236 "RDTG", 1074 "4 RDTG",
1237 "SANGW", 1075 "5 SANGW",
1238 "AA", 1076 "2 AA",
1239 1077
1240 "FlipPT", 1078 "6 FlipPT",
1241 "FlipRgON", 1079 "8 FlipRgON",
1242 "FlipRgOFF", 1080 "9 FlipRgOFF",
1243 "INS_$83", 1081 "7 INS_$83",
1244 "INS_$84", 1082 "7 INS_$84",
1245 "ScanCTRL", 1083 "8 ScanCTRL",
1246 "SDVPTL[0]", 1084 "9 SDPvTL[0]",
1247 "SDVPTL[1]", 1085 "9 SDPvTL[1]",
1248 "GetINFO", 1086 "7 GetINFO",
1249 "IDEF", 1087 "4 IDEF",
1250 "ROLL", 1088 "4 ROLL",
1251 "MAX", 1089 "3 MAX",
1252 "MIN", 1090 "3 MIN",
1253 "ScanTYPE", 1091 "8 ScanTYPE",
1254 "InstCTRL", 1092 "8 InstCTRL",
1255 "INS_$8F", 1093 "7 INS_$8F",
1256 1094
1257 "INS_$90", 1095 "7 INS_$90",
1258 "INS_$91", 1096 "7 INS_$91",
1259 "INS_$92", 1097 "7 INS_$92",
1260 "INS_$93", 1098 "7 INS_$93",
1261 "INS_$94", 1099 "7 INS_$94",
1262 "INS_$95", 1100 "7 INS_$95",
1263 "INS_$96", 1101 "7 INS_$96",
1264 "INS_$97", 1102 "7 INS_$97",
1265 "INS_$98", 1103 "7 INS_$98",
1266 "INS_$99", 1104 "7 INS_$99",
1267 "INS_$9A", 1105 "7 INS_$9A",
1268 "INS_$9B", 1106 "7 INS_$9B",
1269 "INS_$9C", 1107 "7 INS_$9C",
1270 "INS_$9D", 1108 "7 INS_$9D",
1271 "INS_$9E", 1109 "7 INS_$9E",
1272 "INS_$9F", 1110 "7 INS_$9F",
1273 1111
1274 "INS_$A0", 1112 "7 INS_$A0",
1275 "INS_$A1", 1113 "7 INS_$A1",
1276 "INS_$A2", 1114 "7 INS_$A2",
1277 "INS_$A3", 1115 "7 INS_$A3",
1278 "INS_$A4", 1116 "7 INS_$A4",
1279 "INS_$A5", 1117 "7 INS_$A5",
1280 "INS_$A6", 1118 "7 INS_$A6",
1281 "INS_$A7", 1119 "7 INS_$A7",
1282 "INS_$A8", 1120 "7 INS_$A8",
1283 "INS_$A9", 1121 "7 INS_$A9",
1284 "INS_$AA", 1122 "7 INS_$AA",
1285 "INS_$AB", 1123 "7 INS_$AB",
1286 "INS_$AC", 1124 "7 INS_$AC",
1287 "INS_$AD", 1125 "7 INS_$AD",
1288 "INS_$AE", 1126 "7 INS_$AE",
1289 "INS_$AF", 1127 "7 INS_$AF",
1290 1128
1291 "PushB[0]", 1129 "8 PushB[0]",
1292 "PushB[1]", 1130 "8 PushB[1]",
1293 "PushB[2]", 1131 "8 PushB[2]",
1294 "PushB[3]", 1132 "8 PushB[3]",
1295 "PushB[4]", 1133 "8 PushB[4]",
1296 "PushB[5]", 1134 "8 PushB[5]",
1297 "PushB[6]", 1135 "8 PushB[6]",
1298 "PushB[7]", 1136 "8 PushB[7]",
1299 "PushW[0]", 1137 "8 PushW[0]",
1300 "PushW[1]", 1138 "8 PushW[1]",
1301 "PushW[2]", 1139 "8 PushW[2]",
1302 "PushW[3]", 1140 "8 PushW[3]",
1303 "PushW[4]", 1141 "8 PushW[4]",
1304 "PushW[5]", 1142 "8 PushW[5]",
1305 "PushW[6]", 1143 "8 PushW[6]",
1306 "PushW[7]", 1144 "8 PushW[7]",
1307 1145
1308 "MDRP[00]", 1146 "8 MDRP[00]",
1309 "MDRP[01]", 1147 "8 MDRP[01]",
1310 "MDRP[02]", 1148 "8 MDRP[02]",
1311 "MDRP[03]", 1149 "8 MDRP[03]",
1312 "MDRP[04]", 1150 "8 MDRP[04]",
1313 "MDRP[05]", 1151 "8 MDRP[05]",
1314 "MDRP[06]", 1152 "8 MDRP[06]",
1315 "MDRP[07]", 1153 "8 MDRP[07]",
1316 "MDRP[08]", 1154 "8 MDRP[08]",
1317 "MDRP[09]", 1155 "8 MDRP[09]",
1318 "MDRP[10]", 1156 "8 MDRP[10]",
1319 "MDRP[11]", 1157 "8 MDRP[11]",
1320 "MDRP[12]", 1158 "8 MDRP[12]",
1321 "MDRP[13]", 1159 "8 MDRP[13]",
1322 "MDRP[14]", 1160 "8 MDRP[14]",
1323 "MDRP[15]", 1161 "8 MDRP[15]",
1324 1162
1325 "MDRP[16]", 1163 "8 MDRP[16]",
1326 "MDRP[17]", 1164 "8 MDRP[17]",
1327 "MDRP[18]", 1165 "8 MDRP[18]",
1328 "MDRP[19]", 1166 "8 MDRP[19]",
1329 "MDRP[20]", 1167 "8 MDRP[20]",
1330 "MDRP[21]", 1168 "8 MDRP[21]",
1331 "MDRP[22]", 1169 "8 MDRP[22]",
1332 "MDRP[23]", 1170 "8 MDRP[23]",
1333 "MDRP[24]", 1171 "8 MDRP[24]",
1334 "MDRP[25]", 1172 "8 MDRP[25]",
1335 "MDRP[26]", 1173 "8 MDRP[26]",
1336 "MDRP[27]", 1174 "8 MDRP[27]",
1337 "MDRP[28]", 1175 "8 MDRP[28]",
1338 "MDRP[29]", 1176 "8 MDRP[29]",
1339 "MDRP[30]", 1177 "8 MDRP[30]",
1340 "MDRP[31]", 1178 "8 MDRP[31]",
1341 1179
1342 "MIRP[00]", 1180 "8 MIRP[00]",
1343 "MIRP[01]", 1181 "8 MIRP[01]",
1344 "MIRP[02]", 1182 "8 MIRP[02]",
1345 "MIRP[03]", 1183 "8 MIRP[03]",
1346 "MIRP[04]", 1184 "8 MIRP[04]",
1347 "MIRP[05]", 1185 "8 MIRP[05]",
1348 "MIRP[06]", 1186 "8 MIRP[06]",
1349 "MIRP[07]", 1187 "8 MIRP[07]",
1350 "MIRP[08]", 1188 "8 MIRP[08]",
1351 "MIRP[09]", 1189 "8 MIRP[09]",
1352 "MIRP[10]", 1190 "8 MIRP[10]",
1353 "MIRP[11]", 1191 "8 MIRP[11]",
1354 "MIRP[12]", 1192 "8 MIRP[12]",
1355 "MIRP[13]", 1193 "8 MIRP[13]",
1356 "MIRP[14]", 1194 "8 MIRP[14]",
1357 "MIRP[15]", 1195 "8 MIRP[15]",
1358 1196
1359 "MIRP[16]", 1197 "8 MIRP[16]",
1360 "MIRP[17]", 1198 "8 MIRP[17]",
1361 "MIRP[18]", 1199 "8 MIRP[18]",
1362 "MIRP[19]", 1200 "8 MIRP[19]",
1363 "MIRP[20]", 1201 "8 MIRP[20]",
1364 "MIRP[21]", 1202 "8 MIRP[21]",
1365 "MIRP[22]", 1203 "8 MIRP[22]",
1366 "MIRP[23]", 1204 "8 MIRP[23]",
1367 "MIRP[24]", 1205 "8 MIRP[24]",
1368 "MIRP[25]", 1206 "8 MIRP[25]",
1369 "MIRP[26]", 1207 "8 MIRP[26]",
1370 "MIRP[27]", 1208 "8 MIRP[27]",
1371 "MIRP[28]", 1209 "8 MIRP[28]",
1372 "MIRP[29]", 1210 "8 MIRP[29]",
1373 "MIRP[30]", 1211 "8 MIRP[30]",
1374 "MIRP[31]" 1212 "8 MIRP[31]"
1375 }; 1213 };
1376 1214
1377 #endif /* FT_DEBUG_LEVEL_TRACE */ 1215 #endif /* FT_DEBUG_LEVEL_TRACE */
1378 1216
1379 1217
1380 static 1218 static
1381 const FT_Char opcode_length[256] = 1219 const FT_Char opcode_length[256] =
1382 { 1220 {
1383 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1221 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1384 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1222 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 /* Current_Ratio */ 1468 /* Current_Ratio */
1631 /* */ 1469 /* */
1632 /* <Description> */ 1470 /* <Description> */
1633 /* Returns the current aspect ratio scaling factor depending on the */ 1471 /* Returns the current aspect ratio scaling factor depending on the */
1634 /* projection vector's state and device resolutions. */ 1472 /* projection vector's state and device resolutions. */
1635 /* */ 1473 /* */
1636 /* <Return> */ 1474 /* <Return> */
1637 /* The aspect ratio in 16.16 format, always <= 1.0 . */ 1475 /* The aspect ratio in 16.16 format, always <= 1.0 . */
1638 /* */ 1476 /* */
1639 static FT_Long 1477 static FT_Long
1640 Current_Ratio( EXEC_OP ) 1478 Current_Ratio( TT_ExecContext exc )
1641 { 1479 {
1642 if ( !CUR.tt_metrics.ratio ) 1480 if ( !exc->tt_metrics.ratio )
1643 { 1481 {
1644 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 1482 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1645 if ( CUR.face->unpatented_hinting ) 1483 if ( exc->face->unpatented_hinting )
1646 { 1484 {
1647 if ( CUR.GS.both_x_axis ) 1485 if ( exc->GS.both_x_axis )
1648 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; 1486 exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
1649 else 1487 else
1650 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; 1488 exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
1651 } 1489 }
1652 else 1490 else
1653 #endif 1491 #endif
1654 { 1492 {
1655 if ( CUR.GS.projVector.y == 0 ) 1493 if ( exc->GS.projVector.y == 0 )
1656 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; 1494 exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
1657 1495
1658 else if ( CUR.GS.projVector.x == 0 ) 1496 else if ( exc->GS.projVector.x == 0 )
1659 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; 1497 exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
1660 1498
1661 else 1499 else
1662 { 1500 {
1663 FT_F26Dot6 x, y; 1501 FT_F26Dot6 x, y;
1664 1502
1665 1503
1666 x = TT_MulFix14( CUR.tt_metrics.x_ratio, 1504 x = TT_MulFix14( exc->tt_metrics.x_ratio,
1667 CUR.GS.projVector.x ); 1505 exc->GS.projVector.x );
1668 y = TT_MulFix14( CUR.tt_metrics.y_ratio, 1506 y = TT_MulFix14( exc->tt_metrics.y_ratio,
1669 CUR.GS.projVector.y ); 1507 exc->GS.projVector.y );
1670 CUR.tt_metrics.ratio = FT_Hypot( x, y ); 1508 exc->tt_metrics.ratio = FT_Hypot( x, y );
1671 } 1509 }
1672 } 1510 }
1673 } 1511 }
1674 return CUR.tt_metrics.ratio; 1512 return exc->tt_metrics.ratio;
1675 } 1513 }
1676 1514
1677 1515
1678 FT_CALLBACK_DEF( FT_Long ) 1516 FT_CALLBACK_DEF( FT_Long )
1679 Current_Ppem( EXEC_OP ) 1517 Current_Ppem( TT_ExecContext exc )
1680 { 1518 {
1681 return CUR.tt_metrics.ppem; 1519 return exc->tt_metrics.ppem;
1682 } 1520 }
1683 1521
1684 1522
1685 FT_CALLBACK_DEF( FT_Long ) 1523 FT_CALLBACK_DEF( FT_Long )
1686 Current_Ppem_Stretched( EXEC_OP ) 1524 Current_Ppem_Stretched( TT_ExecContext exc )
1687 { 1525 {
1688 return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); 1526 return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
1689 } 1527 }
1690 1528
1691 1529
1692 /*************************************************************************/ 1530 /*************************************************************************/
1693 /* */ 1531 /* */
1694 /* Functions related to the control value table (CVT). */ 1532 /* Functions related to the control value table (CVT). */
1695 /* */ 1533 /* */
1696 /*************************************************************************/ 1534 /*************************************************************************/
1697 1535
1698 1536
1699 FT_CALLBACK_DEF( FT_F26Dot6 ) 1537 FT_CALLBACK_DEF( FT_F26Dot6 )
1700 Read_CVT( EXEC_OP_ FT_ULong idx ) 1538 Read_CVT( TT_ExecContext exc,
1539 FT_ULong idx )
1701 { 1540 {
1702 return CUR.cvt[idx]; 1541 return exc->cvt[idx];
1703 } 1542 }
1704 1543
1705 1544
1706 FT_CALLBACK_DEF( FT_F26Dot6 ) 1545 FT_CALLBACK_DEF( FT_F26Dot6 )
1707 Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) 1546 Read_CVT_Stretched( TT_ExecContext exc,
1547 FT_ULong idx )
1708 { 1548 {
1709 return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); 1549 return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
1710 } 1550 }
1711 1551
1712 1552
1713 FT_CALLBACK_DEF( void ) 1553 FT_CALLBACK_DEF( void )
1714 Write_CVT( EXEC_OP_ FT_ULong idx, 1554 Write_CVT( TT_ExecContext exc,
1715 FT_F26Dot6 value ) 1555 FT_ULong idx,
1556 FT_F26Dot6 value )
1716 { 1557 {
1717 CUR.cvt[idx] = value; 1558 exc->cvt[idx] = value;
1718 } 1559 }
1719 1560
1720 1561
1721 FT_CALLBACK_DEF( void ) 1562 FT_CALLBACK_DEF( void )
1722 Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, 1563 Write_CVT_Stretched( TT_ExecContext exc,
1723 FT_F26Dot6 value ) 1564 FT_ULong idx,
1565 FT_F26Dot6 value )
1724 { 1566 {
1725 CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); 1567 exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
1726 } 1568 }
1727 1569
1728 1570
1729 FT_CALLBACK_DEF( void ) 1571 FT_CALLBACK_DEF( void )
1730 Move_CVT( EXEC_OP_ FT_ULong idx, 1572 Move_CVT( TT_ExecContext exc,
1731 FT_F26Dot6 value ) 1573 FT_ULong idx,
1574 FT_F26Dot6 value )
1732 { 1575 {
1733 CUR.cvt[idx] += value; 1576 exc->cvt[idx] += value;
1734 } 1577 }
1735 1578
1736 1579
1737 FT_CALLBACK_DEF( void ) 1580 FT_CALLBACK_DEF( void )
1738 Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, 1581 Move_CVT_Stretched( TT_ExecContext exc,
1739 FT_F26Dot6 value ) 1582 FT_ULong idx,
1583 FT_F26Dot6 value )
1740 { 1584 {
1741 CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); 1585 exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
1742 } 1586 }
1743 1587
1744 1588
1745 /*************************************************************************/ 1589 /*************************************************************************/
1746 /* */ 1590 /* */
1747 /* <Function> */ 1591 /* <Function> */
1748 /* GetShortIns */ 1592 /* GetShortIns */
1749 /* */ 1593 /* */
1750 /* <Description> */ 1594 /* <Description> */
1751 /* Returns a short integer taken from the instruction stream at */ 1595 /* Returns a short integer taken from the instruction stream at */
1752 /* address IP. */ 1596 /* address IP. */
1753 /* */ 1597 /* */
1754 /* <Return> */ 1598 /* <Return> */
1755 /* Short read at code[IP]. */ 1599 /* Short read at code[IP]. */
1756 /* */ 1600 /* */
1757 /* <Note> */ 1601 /* <Note> */
1758 /* This one could become a macro. */ 1602 /* This one could become a macro. */
1759 /* */ 1603 /* */
1760 static FT_Short 1604 static FT_Short
1761 GetShortIns( EXEC_OP ) 1605 GetShortIns( TT_ExecContext exc )
1762 { 1606 {
1763 /* Reading a byte stream so there is no endianess (DaveP) */ 1607 /* Reading a byte stream so there is no endianess (DaveP) */
1764 CUR.IP += 2; 1608 exc->IP += 2;
1765 return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + 1609 return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
1766 CUR.code[CUR.IP - 1] ); 1610 exc->code[exc->IP - 1] );
1767 } 1611 }
1768 1612
1769 1613
1770 /*************************************************************************/ 1614 /*************************************************************************/
1771 /* */ 1615 /* */
1772 /* <Function> */ 1616 /* <Function> */
1773 /* Ins_Goto_CodeRange */ 1617 /* Ins_Goto_CodeRange */
1774 /* */ 1618 /* */
1775 /* <Description> */ 1619 /* <Description> */
1776 /* Goes to a certain code range in the instruction stream. */ 1620 /* Goes to a certain code range in the instruction stream. */
1777 /* */ 1621 /* */
1778 /* <Input> */ 1622 /* <Input> */
1779 /* aRange :: The index of the code range. */ 1623 /* aRange :: The index of the code range. */
1780 /* */ 1624 /* */
1781 /* aIP :: The new IP address in the code range. */ 1625 /* aIP :: The new IP address in the code range. */
1782 /* */ 1626 /* */
1783 /* <Return> */ 1627 /* <Return> */
1784 /* SUCCESS or FAILURE. */ 1628 /* SUCCESS or FAILURE. */
1785 /* */ 1629 /* */
1786 static FT_Bool 1630 static FT_Bool
1787 Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, 1631 Ins_Goto_CodeRange( TT_ExecContext exc,
1788 FT_ULong aIP ) 1632 FT_Int aRange,
1633 FT_Long aIP )
1789 { 1634 {
1790 TT_CodeRange* range; 1635 TT_CodeRange* range;
1791 1636
1792 1637
1793 if ( aRange < 1 || aRange > 3 ) 1638 if ( aRange < 1 || aRange > 3 )
1794 { 1639 {
1795 CUR.error = FT_THROW( Bad_Argument ); 1640 exc->error = FT_THROW( Bad_Argument );
1796 return FAILURE; 1641 return FAILURE;
1797 } 1642 }
1798 1643
1799 range = &CUR.codeRangeTable[aRange - 1]; 1644 range = &exc->codeRangeTable[aRange - 1];
1800 1645
1801 if ( range->base == NULL ) /* invalid coderange */ 1646 if ( range->base == NULL ) /* invalid coderange */
1802 { 1647 {
1803 CUR.error = FT_THROW( Invalid_CodeRange ); 1648 exc->error = FT_THROW( Invalid_CodeRange );
1804 return FAILURE; 1649 return FAILURE;
1805 } 1650 }
1806 1651
1807 /* NOTE: Because the last instruction of a program may be a CALL */ 1652 /* NOTE: Because the last instruction of a program may be a CALL */
1808 /* which will return to the first byte *after* the code */ 1653 /* which will return to the first byte *after* the code */
1809 /* range, we test for aIP <= Size, instead of aIP < Size. */ 1654 /* range, we test for aIP <= Size, instead of aIP < Size. */
1810 1655
1811 if ( aIP > range->size ) 1656 if ( aIP > range->size )
1812 { 1657 {
1813 CUR.error = FT_THROW( Code_Overflow ); 1658 exc->error = FT_THROW( Code_Overflow );
1814 return FAILURE; 1659 return FAILURE;
1815 } 1660 }
1816 1661
1817 CUR.code = range->base; 1662 exc->code = range->base;
1818 CUR.codeSize = range->size; 1663 exc->codeSize = range->size;
1819 CUR.IP = aIP; 1664 exc->IP = aIP;
1820 CUR.curRange = aRange; 1665 exc->curRange = aRange;
1821 1666
1822 return SUCCESS; 1667 return SUCCESS;
1823 } 1668 }
1824 1669
1825 1670
1826 /*************************************************************************/ 1671 /*************************************************************************/
1827 /* */ 1672 /* */
1828 /* <Function> */ 1673 /* <Function> */
1829 /* Direct_Move */ 1674 /* Direct_Move */
1830 /* */ 1675 /* */
1831 /* <Description> */ 1676 /* <Description> */
1832 /* Moves a point by a given distance along the freedom vector. The */ 1677 /* Moves a point by a given distance along the freedom vector. The */
1833 /* point will be `touched'. */ 1678 /* point will be `touched'. */
1834 /* */ 1679 /* */
1835 /* <Input> */ 1680 /* <Input> */
1836 /* point :: The index of the point to move. */ 1681 /* point :: The index of the point to move. */
1837 /* */ 1682 /* */
1838 /* distance :: The distance to apply. */ 1683 /* distance :: The distance to apply. */
1839 /* */ 1684 /* */
1840 /* <InOut> */ 1685 /* <InOut> */
1841 /* zone :: The affected glyph zone. */ 1686 /* zone :: The affected glyph zone. */
1842 /* */ 1687 /* */
1843 static void 1688 static void
1844 Direct_Move( EXEC_OP_ TT_GlyphZone zone, 1689 Direct_Move( TT_ExecContext exc,
1845 FT_UShort point, 1690 TT_GlyphZone zone,
1846 FT_F26Dot6 distance ) 1691 FT_UShort point,
1692 FT_F26Dot6 distance )
1847 { 1693 {
1848 FT_F26Dot6 v; 1694 FT_F26Dot6 v;
1849 1695
1850 1696
1851 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 1697 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1852 FT_ASSERT( !CUR.face->unpatented_hinting ); 1698 FT_ASSERT( !exc->face->unpatented_hinting );
1853 #endif 1699 #endif
1854 1700
1855 v = CUR.GS.freeVector.x; 1701 v = exc->GS.freeVector.x;
1856 1702
1857 if ( v != 0 ) 1703 if ( v != 0 )
1858 { 1704 {
1859 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 1705 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1860 if ( !SUBPIXEL_HINTING || 1706 if ( !SUBPIXEL_HINTING ||
1861 ( !CUR.ignore_x_mode || 1707 ( !exc->ignore_x_mode ||
1862 ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) 1708 ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
1863 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 1709 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1864 zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); 1710 zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
1865 1711
1866 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; 1712 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
1867 } 1713 }
1868 1714
1869 v = CUR.GS.freeVector.y; 1715 v = exc->GS.freeVector.y;
1870 1716
1871 if ( v != 0 ) 1717 if ( v != 0 )
1872 { 1718 {
1873 zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); 1719 zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
1874 1720
1875 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; 1721 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
1876 } 1722 }
1877 } 1723 }
1878 1724
1879 1725
1880 /*************************************************************************/ 1726 /*************************************************************************/
1881 /* */ 1727 /* */
1882 /* <Function> */ 1728 /* <Function> */
1883 /* Direct_Move_Orig */ 1729 /* Direct_Move_Orig */
1884 /* */ 1730 /* */
1885 /* <Description> */ 1731 /* <Description> */
1886 /* Moves the *original* position of a point by a given distance along */ 1732 /* Moves the *original* position of a point by a given distance along */
1887 /* the freedom vector. Obviously, the point will not be `touched'. */ 1733 /* the freedom vector. Obviously, the point will not be `touched'. */
1888 /* */ 1734 /* */
1889 /* <Input> */ 1735 /* <Input> */
1890 /* point :: The index of the point to move. */ 1736 /* point :: The index of the point to move. */
1891 /* */ 1737 /* */
1892 /* distance :: The distance to apply. */ 1738 /* distance :: The distance to apply. */
1893 /* */ 1739 /* */
1894 /* <InOut> */ 1740 /* <InOut> */
1895 /* zone :: The affected glyph zone. */ 1741 /* zone :: The affected glyph zone. */
1896 /* */ 1742 /* */
1897 static void 1743 static void
1898 Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, 1744 Direct_Move_Orig( TT_ExecContext exc,
1899 FT_UShort point, 1745 TT_GlyphZone zone,
1900 FT_F26Dot6 distance ) 1746 FT_UShort point,
1747 FT_F26Dot6 distance )
1901 { 1748 {
1902 FT_F26Dot6 v; 1749 FT_F26Dot6 v;
1903 1750
1904 1751
1905 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 1752 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1906 FT_ASSERT( !CUR.face->unpatented_hinting ); 1753 FT_ASSERT( !exc->face->unpatented_hinting );
1907 #endif 1754 #endif
1908 1755
1909 v = CUR.GS.freeVector.x; 1756 v = exc->GS.freeVector.x;
1910 1757
1911 if ( v != 0 ) 1758 if ( v != 0 )
1912 zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); 1759 zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
1913 1760
1914 v = CUR.GS.freeVector.y; 1761 v = exc->GS.freeVector.y;
1915 1762
1916 if ( v != 0 ) 1763 if ( v != 0 )
1917 zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); 1764 zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
1918 } 1765 }
1919 1766
1920 1767
1921 /*************************************************************************/ 1768 /*************************************************************************/
1922 /* */ 1769 /* */
1923 /* Special versions of Direct_Move() */ 1770 /* Special versions of Direct_Move() */
1924 /* */ 1771 /* */
1925 /* The following versions are used whenever both vectors are both */ 1772 /* The following versions are used whenever both vectors are both */
1926 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ 1773 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
1927 /* */ 1774 /* */
1928 /*************************************************************************/ 1775 /*************************************************************************/
1929 1776
1930 1777
1931 static void 1778 static void
1932 Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, 1779 Direct_Move_X( TT_ExecContext exc,
1933 FT_UShort point, 1780 TT_GlyphZone zone,
1934 FT_F26Dot6 distance ) 1781 FT_UShort point,
1782 FT_F26Dot6 distance )
1935 { 1783 {
1936 FT_UNUSED_EXEC; 1784 FT_UNUSED( exc );
1937 1785
1938 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 1786 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1939 if ( !SUBPIXEL_HINTING || 1787 if ( !SUBPIXEL_HINTING ||
1940 !CUR.ignore_x_mode ) 1788 !exc->ignore_x_mode )
1941 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 1789 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1942 zone->cur[point].x += distance; 1790 zone->cur[point].x += distance;
1943 1791
1944 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; 1792 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
1945 } 1793 }
1946 1794
1947 1795
1948 static void 1796 static void
1949 Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, 1797 Direct_Move_Y( TT_ExecContext exc,
1950 FT_UShort point, 1798 TT_GlyphZone zone,
1951 FT_F26Dot6 distance ) 1799 FT_UShort point,
1800 FT_F26Dot6 distance )
1952 { 1801 {
1953 FT_UNUSED_EXEC; 1802 FT_UNUSED( exc );
1954 1803
1955 zone->cur[point].y += distance; 1804 zone->cur[point].y += distance;
1956 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; 1805 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
1957 } 1806 }
1958 1807
1959 1808
1960 /*************************************************************************/ 1809 /*************************************************************************/
1961 /* */ 1810 /* */
1962 /* Special versions of Direct_Move_Orig() */ 1811 /* Special versions of Direct_Move_Orig() */
1963 /* */ 1812 /* */
1964 /* The following versions are used whenever both vectors are both */ 1813 /* The following versions are used whenever both vectors are both */
1965 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ 1814 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
1966 /* */ 1815 /* */
1967 /*************************************************************************/ 1816 /*************************************************************************/
1968 1817
1969 1818
1970 static void 1819 static void
1971 Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, 1820 Direct_Move_Orig_X( TT_ExecContext exc,
1972 FT_UShort point, 1821 TT_GlyphZone zone,
1973 FT_F26Dot6 distance ) 1822 FT_UShort point,
1823 FT_F26Dot6 distance )
1974 { 1824 {
1975 FT_UNUSED_EXEC; 1825 FT_UNUSED( exc );
1976 1826
1977 zone->org[point].x += distance; 1827 zone->org[point].x += distance;
1978 } 1828 }
1979 1829
1980 1830
1981 static void 1831 static void
1982 Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, 1832 Direct_Move_Orig_Y( TT_ExecContext exc,
1983 FT_UShort point, 1833 TT_GlyphZone zone,
1984 FT_F26Dot6 distance ) 1834 FT_UShort point,
1835 FT_F26Dot6 distance )
1985 { 1836 {
1986 FT_UNUSED_EXEC; 1837 FT_UNUSED( exc );
1987 1838
1988 zone->org[point].y += distance; 1839 zone->org[point].y += distance;
1989 } 1840 }
1990 1841
1991 1842
1992 /*************************************************************************/ 1843 /*************************************************************************/
1993 /* */ 1844 /* */
1994 /* <Function> */ 1845 /* <Function> */
1995 /* Round_None */ 1846 /* Round_None */
1996 /* */ 1847 /* */
1997 /* <Description> */ 1848 /* <Description> */
1998 /* Does not round, but adds engine compensation. */ 1849 /* Does not round, but adds engine compensation. */
1999 /* */ 1850 /* */
2000 /* <Input> */ 1851 /* <Input> */
2001 /* distance :: The distance (not) to round. */ 1852 /* distance :: The distance (not) to round. */
2002 /* */ 1853 /* */
2003 /* compensation :: The engine compensation. */ 1854 /* compensation :: The engine compensation. */
2004 /* */ 1855 /* */
2005 /* <Return> */ 1856 /* <Return> */
2006 /* The compensated distance. */ 1857 /* The compensated distance. */
2007 /* */ 1858 /* */
2008 /* <Note> */ 1859 /* <Note> */
2009 /* The TrueType specification says very few about the relationship */ 1860 /* The TrueType specification says very few about the relationship */
2010 /* between rounding and engine compensation. However, it seems from */ 1861 /* between rounding and engine compensation. However, it seems from */
2011 /* the description of super round that we should add the compensation */ 1862 /* the description of super round that we should add the compensation */
2012 /* before rounding. */ 1863 /* before rounding. */
2013 /* */ 1864 /* */
2014 static FT_F26Dot6 1865 static FT_F26Dot6
2015 Round_None( EXEC_OP_ FT_F26Dot6 distance, 1866 Round_None( TT_ExecContext exc,
2016 FT_F26Dot6 compensation ) 1867 FT_F26Dot6 distance,
1868 FT_F26Dot6 compensation )
2017 { 1869 {
2018 FT_F26Dot6 val; 1870 FT_F26Dot6 val;
2019 1871
2020 FT_UNUSED_EXEC; 1872 FT_UNUSED( exc );
2021 1873
2022 1874
2023 if ( distance >= 0 ) 1875 if ( distance >= 0 )
2024 { 1876 {
2025 val = distance + compensation; 1877 val = distance + compensation;
2026 if ( val < 0 ) 1878 if ( val < 0 )
2027 val = 0; 1879 val = 0;
2028 } 1880 }
2029 else 1881 else
2030 { 1882 {
(...skipping 15 matching lines...) Expand all
2046 /* */ 1898 /* */
2047 /* <Input> */ 1899 /* <Input> */
2048 /* distance :: The distance to round. */ 1900 /* distance :: The distance to round. */
2049 /* */ 1901 /* */
2050 /* compensation :: The engine compensation. */ 1902 /* compensation :: The engine compensation. */
2051 /* */ 1903 /* */
2052 /* <Return> */ 1904 /* <Return> */
2053 /* Rounded distance. */ 1905 /* Rounded distance. */
2054 /* */ 1906 /* */
2055 static FT_F26Dot6 1907 static FT_F26Dot6
2056 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 1908 Round_To_Grid( TT_ExecContext exc,
2057 FT_F26Dot6 compensation ) 1909 FT_F26Dot6 distance,
1910 FT_F26Dot6 compensation )
2058 { 1911 {
2059 FT_F26Dot6 val; 1912 FT_F26Dot6 val;
2060 1913
2061 FT_UNUSED_EXEC; 1914 FT_UNUSED( exc );
2062 1915
2063 1916
2064 if ( distance >= 0 ) 1917 if ( distance >= 0 )
2065 { 1918 {
2066 val = FT_PIX_ROUND( distance + compensation ); 1919 val = FT_PIX_ROUND( distance + compensation );
2067 if ( val < 0 ) 1920 if ( val < 0 )
2068 val = 0; 1921 val = 0;
2069 } 1922 }
2070 else 1923 else
2071 { 1924 {
2072 val = -FT_PIX_ROUND( compensation - distance ); 1925 val = -FT_PIX_ROUND( compensation - distance );
2073 if ( val > 0 ) 1926 if ( val > 0 )
2074 val = 0; 1927 val = 0;
2075 } 1928 }
2076 1929
2077 return val; 1930 return val;
2078 } 1931 }
2079 1932
2080 1933
2081 /*************************************************************************/ 1934 /*************************************************************************/
2082 /* */ 1935 /* */
2083 /* <Function> */ 1936 /* <Function> */
2084 /* Round_To_Half_Grid */ 1937 /* Round_To_Half_Grid */
2085 /* */ 1938 /* */
2086 /* <Description> */ 1939 /* <Description> */
2087 /* Rounds value to half grid after adding engine compensation. */ 1940 /* Rounds value to half grid after adding engine compensation. */
2088 /* */ 1941 /* */
2089 /* <Input> */ 1942 /* <Input> */
2090 /* distance :: The distance to round. */ 1943 /* distance :: The distance to round. */
2091 /* */ 1944 /* */
2092 /* compensation :: The engine compensation. */ 1945 /* compensation :: The engine compensation. */
2093 /* */ 1946 /* */
2094 /* <Return> */ 1947 /* <Return> */
2095 /* Rounded distance. */ 1948 /* Rounded distance. */
2096 /* */ 1949 /* */
2097 static FT_F26Dot6 1950 static FT_F26Dot6
2098 Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, 1951 Round_To_Half_Grid( TT_ExecContext exc,
2099 FT_F26Dot6 compensation ) 1952 FT_F26Dot6 distance,
1953 FT_F26Dot6 compensation )
2100 { 1954 {
2101 FT_F26Dot6 val; 1955 FT_F26Dot6 val;
2102 1956
2103 FT_UNUSED_EXEC; 1957 FT_UNUSED( exc );
2104 1958
2105 1959
2106 if ( distance >= 0 ) 1960 if ( distance >= 0 )
2107 { 1961 {
2108 val = FT_PIX_FLOOR( distance + compensation ) + 32; 1962 val = FT_PIX_FLOOR( distance + compensation ) + 32;
2109 if ( val < 0 ) 1963 if ( val < 0 )
2110 val = 32; 1964 val = 32;
2111 } 1965 }
2112 else 1966 else
2113 { 1967 {
(...skipping 16 matching lines...) Expand all
2130 /* */ 1984 /* */
2131 /* <Input> */ 1985 /* <Input> */
2132 /* distance :: The distance to round. */ 1986 /* distance :: The distance to round. */
2133 /* */ 1987 /* */
2134 /* compensation :: The engine compensation. */ 1988 /* compensation :: The engine compensation. */
2135 /* */ 1989 /* */
2136 /* <Return> */ 1990 /* <Return> */
2137 /* Rounded distance. */ 1991 /* Rounded distance. */
2138 /* */ 1992 /* */
2139 static FT_F26Dot6 1993 static FT_F26Dot6
2140 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 1994 Round_Down_To_Grid( TT_ExecContext exc,
2141 FT_F26Dot6 compensation ) 1995 FT_F26Dot6 distance,
1996 FT_F26Dot6 compensation )
2142 { 1997 {
2143 FT_F26Dot6 val; 1998 FT_F26Dot6 val;
2144 1999
2145 FT_UNUSED_EXEC; 2000 FT_UNUSED( exc );
2146 2001
2147 2002
2148 if ( distance >= 0 ) 2003 if ( distance >= 0 )
2149 { 2004 {
2150 val = FT_PIX_FLOOR( distance + compensation ); 2005 val = FT_PIX_FLOOR( distance + compensation );
2151 if ( val < 0 ) 2006 if ( val < 0 )
2152 val = 0; 2007 val = 0;
2153 } 2008 }
2154 else 2009 else
2155 { 2010 {
(...skipping 16 matching lines...) Expand all
2172 /* */ 2027 /* */
2173 /* <Input> */ 2028 /* <Input> */
2174 /* distance :: The distance to round. */ 2029 /* distance :: The distance to round. */
2175 /* */ 2030 /* */
2176 /* compensation :: The engine compensation. */ 2031 /* compensation :: The engine compensation. */
2177 /* */ 2032 /* */
2178 /* <Return> */ 2033 /* <Return> */
2179 /* Rounded distance. */ 2034 /* Rounded distance. */
2180 /* */ 2035 /* */
2181 static FT_F26Dot6 2036 static FT_F26Dot6
2182 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 2037 Round_Up_To_Grid( TT_ExecContext exc,
2183 FT_F26Dot6 compensation ) 2038 FT_F26Dot6 distance,
2039 FT_F26Dot6 compensation )
2184 { 2040 {
2185 FT_F26Dot6 val; 2041 FT_F26Dot6 val;
2186 2042
2187 FT_UNUSED_EXEC; 2043 FT_UNUSED( exc );
2188 2044
2189 2045
2190 if ( distance >= 0 ) 2046 if ( distance >= 0 )
2191 { 2047 {
2192 val = FT_PIX_CEIL( distance + compensation ); 2048 val = FT_PIX_CEIL( distance + compensation );
2193 if ( val < 0 ) 2049 if ( val < 0 )
2194 val = 0; 2050 val = 0;
2195 } 2051 }
2196 else 2052 else
2197 { 2053 {
(...skipping 16 matching lines...) Expand all
2214 /* */ 2070 /* */
2215 /* <Input> */ 2071 /* <Input> */
2216 /* distance :: The distance to round. */ 2072 /* distance :: The distance to round. */
2217 /* */ 2073 /* */
2218 /* compensation :: The engine compensation. */ 2074 /* compensation :: The engine compensation. */
2219 /* */ 2075 /* */
2220 /* <Return> */ 2076 /* <Return> */
2221 /* Rounded distance. */ 2077 /* Rounded distance. */
2222 /* */ 2078 /* */
2223 static FT_F26Dot6 2079 static FT_F26Dot6
2224 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, 2080 Round_To_Double_Grid( TT_ExecContext exc,
2225 FT_F26Dot6 compensation ) 2081 FT_F26Dot6 distance,
2082 FT_F26Dot6 compensation )
2226 { 2083 {
2227 FT_F26Dot6 val; 2084 FT_F26Dot6 val;
2228 2085
2229 FT_UNUSED_EXEC; 2086 FT_UNUSED( exc );
2230 2087
2231 2088
2232 if ( distance >= 0 ) 2089 if ( distance >= 0 )
2233 { 2090 {
2234 val = FT_PAD_ROUND( distance + compensation, 32 ); 2091 val = FT_PAD_ROUND( distance + compensation, 32 );
2235 if ( val < 0 ) 2092 if ( val < 0 )
2236 val = 0; 2093 val = 0;
2237 } 2094 }
2238 else 2095 else
2239 { 2096 {
(...skipping 22 matching lines...) Expand all
2262 /* <Return> */ 2119 /* <Return> */
2263 /* Rounded distance. */ 2120 /* Rounded distance. */
2264 /* */ 2121 /* */
2265 /* <Note> */ 2122 /* <Note> */
2266 /* The TrueType specification says very few about the relationship */ 2123 /* The TrueType specification says very few about the relationship */
2267 /* between rounding and engine compensation. However, it seems from */ 2124 /* between rounding and engine compensation. However, it seems from */
2268 /* the description of super round that we should add the compensation */ 2125 /* the description of super round that we should add the compensation */
2269 /* before rounding. */ 2126 /* before rounding. */
2270 /* */ 2127 /* */
2271 static FT_F26Dot6 2128 static FT_F26Dot6
2272 Round_Super( EXEC_OP_ FT_F26Dot6 distance, 2129 Round_Super( TT_ExecContext exc,
2273 FT_F26Dot6 compensation ) 2130 FT_F26Dot6 distance,
2131 FT_F26Dot6 compensation )
2274 { 2132 {
2275 FT_F26Dot6 val; 2133 FT_F26Dot6 val;
2276 2134
2277 2135
2278 if ( distance >= 0 ) 2136 if ( distance >= 0 )
2279 { 2137 {
2280 val = ( distance - CUR.phase + CUR.threshold + compensation ) & 2138 val = ( distance - exc->phase + exc->threshold + compensation ) &
2281 -CUR.period; 2139 -exc->period;
2282 val += CUR.phase; 2140 val += exc->phase;
2283 if ( val < 0 ) 2141 if ( val < 0 )
2284 val = CUR.phase; 2142 val = exc->phase;
2285 } 2143 }
2286 else 2144 else
2287 { 2145 {
2288 val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & 2146 val = -( ( exc->threshold - exc->phase - distance + compensation ) &
2289 -CUR.period ); 2147 -exc->period );
2290 val -= CUR.phase; 2148 val -= exc->phase;
2291 if ( val > 0 ) 2149 if ( val > 0 )
2292 val = -CUR.phase; 2150 val = -exc->phase;
2293 } 2151 }
2294 2152
2295 return val; 2153 return val;
2296 } 2154 }
2297 2155
2298 2156
2299 /*************************************************************************/ 2157 /*************************************************************************/
2300 /* */ 2158 /* */
2301 /* <Function> */ 2159 /* <Function> */
2302 /* Round_Super_45 */ 2160 /* Round_Super_45 */
2303 /* */ 2161 /* */
2304 /* <Description> */ 2162 /* <Description> */
2305 /* Super-rounds value to grid after adding engine compensation. */ 2163 /* Super-rounds value to grid after adding engine compensation. */
2306 /* */ 2164 /* */
2307 /* <Input> */ 2165 /* <Input> */
2308 /* distance :: The distance to round. */ 2166 /* distance :: The distance to round. */
2309 /* */ 2167 /* */
2310 /* compensation :: The engine compensation. */ 2168 /* compensation :: The engine compensation. */
2311 /* */ 2169 /* */
2312 /* <Return> */ 2170 /* <Return> */
2313 /* Rounded distance. */ 2171 /* Rounded distance. */
2314 /* */ 2172 /* */
2315 /* <Note> */ 2173 /* <Note> */
2316 /* There is a separate function for Round_Super_45() as we may need */ 2174 /* There is a separate function for Round_Super_45() as we may need */
2317 /* greater precision. */ 2175 /* greater precision. */
2318 /* */ 2176 /* */
2319 static FT_F26Dot6 2177 static FT_F26Dot6
2320 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, 2178 Round_Super_45( TT_ExecContext exc,
2321 FT_F26Dot6 compensation ) 2179 FT_F26Dot6 distance,
2180 FT_F26Dot6 compensation )
2322 { 2181 {
2323 FT_F26Dot6 val; 2182 FT_F26Dot6 val;
2324 2183
2325 2184
2326 if ( distance >= 0 ) 2185 if ( distance >= 0 )
2327 { 2186 {
2328 val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / 2187 val = ( ( distance - exc->phase + exc->threshold + compensation ) /
2329 CUR.period ) * CUR.period; 2188 exc->period ) * exc->period;
2330 val += CUR.phase; 2189 val += exc->phase;
2331 if ( val < 0 ) 2190 if ( val < 0 )
2332 val = CUR.phase; 2191 val = exc->phase;
2333 } 2192 }
2334 else 2193 else
2335 { 2194 {
2336 val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / 2195 val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
2337 CUR.period ) * CUR.period ); 2196 exc->period ) * exc->period );
2338 val -= CUR.phase; 2197 val -= exc->phase;
2339 if ( val > 0 ) 2198 if ( val > 0 )
2340 val = -CUR.phase; 2199 val = -exc->phase;
2341 } 2200 }
2342 2201
2343 return val; 2202 return val;
2344 } 2203 }
2345 2204
2346 2205
2347 /*************************************************************************/ 2206 /*************************************************************************/
2348 /* */ 2207 /* */
2349 /* <Function> */ 2208 /* <Function> */
2350 /* Compute_Round */ 2209 /* Compute_Round */
2351 /* */ 2210 /* */
2352 /* <Description> */ 2211 /* <Description> */
2353 /* Sets the rounding mode. */ 2212 /* Sets the rounding mode. */
2354 /* */ 2213 /* */
2355 /* <Input> */ 2214 /* <Input> */
2356 /* round_mode :: The rounding mode to be used. */ 2215 /* round_mode :: The rounding mode to be used. */
2357 /* */ 2216 /* */
2358 static void 2217 static void
2359 Compute_Round( EXEC_OP_ FT_Byte round_mode ) 2218 Compute_Round( TT_ExecContext exc,
2219 FT_Byte round_mode )
2360 { 2220 {
2361 switch ( round_mode ) 2221 switch ( round_mode )
2362 { 2222 {
2363 case TT_Round_Off: 2223 case TT_Round_Off:
2364 CUR.func_round = (TT_Round_Func)Round_None; 2224 exc->func_round = (TT_Round_Func)Round_None;
2365 break; 2225 break;
2366 2226
2367 case TT_Round_To_Grid: 2227 case TT_Round_To_Grid:
2368 CUR.func_round = (TT_Round_Func)Round_To_Grid; 2228 exc->func_round = (TT_Round_Func)Round_To_Grid;
2369 break; 2229 break;
2370 2230
2371 case TT_Round_Up_To_Grid: 2231 case TT_Round_Up_To_Grid:
2372 CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; 2232 exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
2373 break; 2233 break;
2374 2234
2375 case TT_Round_Down_To_Grid: 2235 case TT_Round_Down_To_Grid:
2376 CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; 2236 exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
2377 break; 2237 break;
2378 2238
2379 case TT_Round_To_Half_Grid: 2239 case TT_Round_To_Half_Grid:
2380 CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; 2240 exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
2381 break; 2241 break;
2382 2242
2383 case TT_Round_To_Double_Grid: 2243 case TT_Round_To_Double_Grid:
2384 CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; 2244 exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
2385 break; 2245 break;
2386 2246
2387 case TT_Round_Super: 2247 case TT_Round_Super:
2388 CUR.func_round = (TT_Round_Func)Round_Super; 2248 exc->func_round = (TT_Round_Func)Round_Super;
2389 break; 2249 break;
2390 2250
2391 case TT_Round_Super_45: 2251 case TT_Round_Super_45:
2392 CUR.func_round = (TT_Round_Func)Round_Super_45; 2252 exc->func_round = (TT_Round_Func)Round_Super_45;
2393 break; 2253 break;
2394 } 2254 }
2395 } 2255 }
2396 2256
2397 2257
2398 /*************************************************************************/ 2258 /*************************************************************************/
2399 /* */ 2259 /* */
2400 /* <Function> */ 2260 /* <Function> */
2401 /* SetSuperRound */ 2261 /* SetSuperRound */
2402 /* */ 2262 /* */
2403 /* <Description> */ 2263 /* <Description> */
2404 /* Sets Super Round parameters. */ 2264 /* Sets Super Round parameters. */
2405 /* */ 2265 /* */
2406 /* <Input> */ 2266 /* <Input> */
2407 /* GridPeriod :: The grid period. */ 2267 /* GridPeriod :: The grid period. */
2408 /* */ 2268 /* */
2409 /* selector :: The SROUND opcode. */ 2269 /* selector :: The SROUND opcode. */
2410 /* */ 2270 /* */
2411 static void 2271 static void
2412 SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, 2272 SetSuperRound( TT_ExecContext exc,
2413 FT_Long selector ) 2273 FT_F2Dot14 GridPeriod,
2274 FT_Long selector )
2414 { 2275 {
2415 switch ( (FT_Int)( selector & 0xC0 ) ) 2276 switch ( (FT_Int)( selector & 0xC0 ) )
2416 { 2277 {
2417 case 0: 2278 case 0:
2418 CUR.period = GridPeriod / 2; 2279 exc->period = GridPeriod / 2;
2419 break; 2280 break;
2420 2281
2421 case 0x40: 2282 case 0x40:
2422 CUR.period = GridPeriod; 2283 exc->period = GridPeriod;
2423 break; 2284 break;
2424 2285
2425 case 0x80: 2286 case 0x80:
2426 CUR.period = GridPeriod * 2; 2287 exc->period = GridPeriod * 2;
2427 break; 2288 break;
2428 2289
2429 /* This opcode is reserved, but... */ 2290 /* This opcode is reserved, but... */
2430
2431 case 0xC0: 2291 case 0xC0:
2432 CUR.period = GridPeriod; 2292 exc->period = GridPeriod;
2433 break; 2293 break;
2434 } 2294 }
2435 2295
2436 switch ( (FT_Int)( selector & 0x30 ) ) 2296 switch ( (FT_Int)( selector & 0x30 ) )
2437 { 2297 {
2438 case 0: 2298 case 0:
2439 CUR.phase = 0; 2299 exc->phase = 0;
2440 break; 2300 break;
2441 2301
2442 case 0x10: 2302 case 0x10:
2443 CUR.phase = CUR.period / 4; 2303 exc->phase = exc->period / 4;
2444 break; 2304 break;
2445 2305
2446 case 0x20: 2306 case 0x20:
2447 CUR.phase = CUR.period / 2; 2307 exc->phase = exc->period / 2;
2448 break; 2308 break;
2449 2309
2450 case 0x30: 2310 case 0x30:
2451 CUR.phase = CUR.period * 3 / 4; 2311 exc->phase = exc->period * 3 / 4;
2452 break; 2312 break;
2453 } 2313 }
2454 2314
2455 if ( ( selector & 0x0F ) == 0 ) 2315 if ( ( selector & 0x0F ) == 0 )
2456 CUR.threshold = CUR.period - 1; 2316 exc->threshold = exc->period - 1;
2457 else 2317 else
2458 CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; 2318 exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
2459 2319
2460 CUR.period /= 256; 2320 /* convert to F26Dot6 format */
2461 CUR.phase /= 256; 2321 exc->period >>= 8;
2462 CUR.threshold /= 256; 2322 exc->phase >>= 8;
2323 exc->threshold >>= 8;
2463 } 2324 }
2464 2325
2465 2326
2466 /*************************************************************************/ 2327 /*************************************************************************/
2467 /* */ 2328 /* */
2468 /* <Function> */ 2329 /* <Function> */
2469 /* Project */ 2330 /* Project */
2470 /* */ 2331 /* */
2471 /* <Description> */ 2332 /* <Description> */
2472 /* Computes the projection of vector given by (v2-v1) along the */ 2333 /* Computes the projection of vector given by (v2-v1) along the */
2473 /* current projection vector. */ 2334 /* current projection vector. */
2474 /* */ 2335 /* */
2475 /* <Input> */ 2336 /* <Input> */
2476 /* v1 :: First input vector. */ 2337 /* v1 :: First input vector. */
2477 /* v2 :: Second input vector. */ 2338 /* v2 :: Second input vector. */
2478 /* */ 2339 /* */
2479 /* <Return> */ 2340 /* <Return> */
2480 /* The distance in F26dot6 format. */ 2341 /* The distance in F26dot6 format. */
2481 /* */ 2342 /* */
2482 static FT_F26Dot6 2343 static FT_F26Dot6
2483 Project( EXEC_OP_ FT_Pos dx, 2344 Project( TT_ExecContext exc,
2484 FT_Pos dy ) 2345 FT_Pos dx,
2346 FT_Pos dy )
2485 { 2347 {
2486 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 2348 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2487 FT_ASSERT( !CUR.face->unpatented_hinting ); 2349 FT_ASSERT( !exc->face->unpatented_hinting );
2488 #endif 2350 #endif
2489 2351
2490 return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, 2352 return TT_DotFix14( dx, dy,
2491 CUR.GS.projVector.x, 2353 exc->GS.projVector.x,
2492 CUR.GS.projVector.y ); 2354 exc->GS.projVector.y );
2493 } 2355 }
2494 2356
2495 2357
2496 /*************************************************************************/ 2358 /*************************************************************************/
2497 /* */ 2359 /* */
2498 /* <Function> */ 2360 /* <Function> */
2499 /* Dual_Project */ 2361 /* Dual_Project */
2500 /* */ 2362 /* */
2501 /* <Description> */ 2363 /* <Description> */
2502 /* Computes the projection of the vector given by (v2-v1) along the */ 2364 /* Computes the projection of the vector given by (v2-v1) along the */
2503 /* current dual vector. */ 2365 /* current dual vector. */
2504 /* */ 2366 /* */
2505 /* <Input> */ 2367 /* <Input> */
2506 /* v1 :: First input vector. */ 2368 /* v1 :: First input vector. */
2507 /* v2 :: Second input vector. */ 2369 /* v2 :: Second input vector. */
2508 /* */ 2370 /* */
2509 /* <Return> */ 2371 /* <Return> */
2510 /* The distance in F26dot6 format. */ 2372 /* The distance in F26dot6 format. */
2511 /* */ 2373 /* */
2512 static FT_F26Dot6 2374 static FT_F26Dot6
2513 Dual_Project( EXEC_OP_ FT_Pos dx, 2375 Dual_Project( TT_ExecContext exc,
2514 FT_Pos dy ) 2376 FT_Pos dx,
2377 FT_Pos dy )
2515 { 2378 {
2516 return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, 2379 return TT_DotFix14( dx, dy,
2517 CUR.GS.dualVector.x, 2380 exc->GS.dualVector.x,
2518 CUR.GS.dualVector.y ); 2381 exc->GS.dualVector.y );
2519 } 2382 }
2520 2383
2521 2384
2522 /*************************************************************************/ 2385 /*************************************************************************/
2523 /* */ 2386 /* */
2524 /* <Function> */ 2387 /* <Function> */
2525 /* Project_x */ 2388 /* Project_x */
2526 /* */ 2389 /* */
2527 /* <Description> */ 2390 /* <Description> */
2528 /* Computes the projection of the vector given by (v2-v1) along the */ 2391 /* Computes the projection of the vector given by (v2-v1) along the */
2529 /* horizontal axis. */ 2392 /* horizontal axis. */
2530 /* */ 2393 /* */
2531 /* <Input> */ 2394 /* <Input> */
2532 /* v1 :: First input vector. */ 2395 /* v1 :: First input vector. */
2533 /* v2 :: Second input vector. */ 2396 /* v2 :: Second input vector. */
2534 /* */ 2397 /* */
2535 /* <Return> */ 2398 /* <Return> */
2536 /* The distance in F26dot6 format. */ 2399 /* The distance in F26dot6 format. */
2537 /* */ 2400 /* */
2538 static FT_F26Dot6 2401 static FT_F26Dot6
2539 Project_x( EXEC_OP_ FT_Pos dx, 2402 Project_x( TT_ExecContext exc,
2540 FT_Pos dy ) 2403 FT_Pos dx,
2404 FT_Pos dy )
2541 { 2405 {
2542 FT_UNUSED_EXEC; 2406 FT_UNUSED( exc );
2543 FT_UNUSED( dy ); 2407 FT_UNUSED( dy );
2544 2408
2545 return dx; 2409 return dx;
2546 } 2410 }
2547 2411
2548 2412
2549 /*************************************************************************/ 2413 /*************************************************************************/
2550 /* */ 2414 /* */
2551 /* <Function> */ 2415 /* <Function> */
2552 /* Project_y */ 2416 /* Project_y */
2553 /* */ 2417 /* */
2554 /* <Description> */ 2418 /* <Description> */
2555 /* Computes the projection of the vector given by (v2-v1) along the */ 2419 /* Computes the projection of the vector given by (v2-v1) along the */
2556 /* vertical axis. */ 2420 /* vertical axis. */
2557 /* */ 2421 /* */
2558 /* <Input> */ 2422 /* <Input> */
2559 /* v1 :: First input vector. */ 2423 /* v1 :: First input vector. */
2560 /* v2 :: Second input vector. */ 2424 /* v2 :: Second input vector. */
2561 /* */ 2425 /* */
2562 /* <Return> */ 2426 /* <Return> */
2563 /* The distance in F26dot6 format. */ 2427 /* The distance in F26dot6 format. */
2564 /* */ 2428 /* */
2565 static FT_F26Dot6 2429 static FT_F26Dot6
2566 Project_y( EXEC_OP_ FT_Pos dx, 2430 Project_y( TT_ExecContext exc,
2567 FT_Pos dy ) 2431 FT_Pos dx,
2432 FT_Pos dy )
2568 { 2433 {
2569 FT_UNUSED_EXEC; 2434 FT_UNUSED( exc );
2570 FT_UNUSED( dx ); 2435 FT_UNUSED( dx );
2571 2436
2572 return dy; 2437 return dy;
2573 } 2438 }
2574 2439
2575 2440
2576 /*************************************************************************/ 2441 /*************************************************************************/
2577 /* */ 2442 /* */
2578 /* <Function> */ 2443 /* <Function> */
2579 /* Compute_Funcs */ 2444 /* Compute_Funcs */
2580 /* */ 2445 /* */
2581 /* <Description> */ 2446 /* <Description> */
2582 /* Computes the projection and movement function pointers according */ 2447 /* Computes the projection and movement function pointers according */
2583 /* to the current graphics state. */ 2448 /* to the current graphics state. */
2584 /* */ 2449 /* */
2585 static void 2450 static void
2586 Compute_Funcs( EXEC_OP ) 2451 Compute_Funcs( TT_ExecContext exc )
2587 { 2452 {
2588 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 2453 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2589 if ( CUR.face->unpatented_hinting ) 2454 if ( exc->face->unpatented_hinting )
2590 { 2455 {
2591 /* If both vectors point rightwards along the x axis, set */ 2456 /* If both vectors point rightwards along the x axis, set */
2592 /* `both-x-axis' true, otherwise set it false. The x values only */ 2457 /* `both-x-axis' true, otherwise set it false. The x values only */
2593 /* need be tested because the vector has been normalised to a unit */ 2458 /* need be tested because the vector has been normalised to a unit */
2594 /* vector of length 0x4000 = unity. */ 2459 /* vector of length 0x4000 = unity. */
2595 CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && 2460 exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
2596 CUR.GS.freeVector.x == 0x4000 ); 2461 exc->GS.freeVector.x == 0x4000 );
2597 2462
2598 /* Throw away projection and freedom vector information */ 2463 /* Throw away projection and freedom vector information */
2599 /* because the patents don't allow them to be stored. */ 2464 /* because the patents don't allow them to be stored. */
2600 /* The relevant US Patents are 5155805 and 5325479. */ 2465 /* The relevant US Patents are 5155805 and 5325479. */
2601 CUR.GS.projVector.x = 0; 2466 exc->GS.projVector.x = 0;
2602 CUR.GS.projVector.y = 0; 2467 exc->GS.projVector.y = 0;
2603 CUR.GS.freeVector.x = 0; 2468 exc->GS.freeVector.x = 0;
2604 CUR.GS.freeVector.y = 0; 2469 exc->GS.freeVector.y = 0;
2605 2470
2606 if ( CUR.GS.both_x_axis ) 2471 if ( exc->GS.both_x_axis )
2607 { 2472 {
2608 CUR.func_project = Project_x; 2473 exc->func_project = Project_x;
2609 CUR.func_move = Direct_Move_X; 2474 exc->func_move = Direct_Move_X;
2610 CUR.func_move_orig = Direct_Move_Orig_X; 2475 exc->func_move_orig = Direct_Move_Orig_X;
2611 } 2476 }
2612 else 2477 else
2613 { 2478 {
2614 CUR.func_project = Project_y; 2479 exc->func_project = Project_y;
2615 CUR.func_move = Direct_Move_Y; 2480 exc->func_move = Direct_Move_Y;
2616 CUR.func_move_orig = Direct_Move_Orig_Y; 2481 exc->func_move_orig = Direct_Move_Orig_Y;
2617 } 2482 }
2618 2483
2619 if ( CUR.GS.dualVector.x == 0x4000 ) 2484 if ( exc->GS.dualVector.x == 0x4000 )
2620 CUR.func_dualproj = Project_x; 2485 exc->func_dualproj = Project_x;
2621 else if ( CUR.GS.dualVector.y == 0x4000 ) 2486 else if ( exc->GS.dualVector.y == 0x4000 )
2622 CUR.func_dualproj = Project_y; 2487 exc->func_dualproj = Project_y;
2623 else 2488 else
2624 CUR.func_dualproj = Dual_Project; 2489 exc->func_dualproj = Dual_Project;
2625 2490
2626 /* Force recalculation of cached aspect ratio */ 2491 /* Force recalculation of cached aspect ratio */
2627 CUR.tt_metrics.ratio = 0; 2492 exc->tt_metrics.ratio = 0;
2628 2493
2629 return; 2494 return;
2630 } 2495 }
2631 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ 2496 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
2632 2497
2633 if ( CUR.GS.freeVector.x == 0x4000 ) 2498 if ( exc->GS.freeVector.x == 0x4000 )
2634 CUR.F_dot_P = CUR.GS.projVector.x; 2499 exc->F_dot_P = exc->GS.projVector.x;
2635 else if ( CUR.GS.freeVector.y == 0x4000 ) 2500 else if ( exc->GS.freeVector.y == 0x4000 )
2636 CUR.F_dot_P = CUR.GS.projVector.y; 2501 exc->F_dot_P = exc->GS.projVector.y;
2637 else 2502 else
2638 CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + 2503 exc->F_dot_P =
2639 (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> 2504 ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
2640 14; 2505 (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
2641 2506
2642 if ( CUR.GS.projVector.x == 0x4000 ) 2507 if ( exc->GS.projVector.x == 0x4000 )
2643 CUR.func_project = (TT_Project_Func)Project_x; 2508 exc->func_project = (TT_Project_Func)Project_x;
2644 else if ( CUR.GS.projVector.y == 0x4000 ) 2509 else if ( exc->GS.projVector.y == 0x4000 )
2645 CUR.func_project = (TT_Project_Func)Project_y; 2510 exc->func_project = (TT_Project_Func)Project_y;
2646 else 2511 else
2647 CUR.func_project = (TT_Project_Func)Project; 2512 exc->func_project = (TT_Project_Func)Project;
2648 2513
2649 if ( CUR.GS.dualVector.x == 0x4000 ) 2514 if ( exc->GS.dualVector.x == 0x4000 )
2650 CUR.func_dualproj = (TT_Project_Func)Project_x; 2515 exc->func_dualproj = (TT_Project_Func)Project_x;
2651 else if ( CUR.GS.dualVector.y == 0x4000 ) 2516 else if ( exc->GS.dualVector.y == 0x4000 )
2652 CUR.func_dualproj = (TT_Project_Func)Project_y; 2517 exc->func_dualproj = (TT_Project_Func)Project_y;
2653 else 2518 else
2654 CUR.func_dualproj = (TT_Project_Func)Dual_Project; 2519 exc->func_dualproj = (TT_Project_Func)Dual_Project;
2655 2520
2656 CUR.func_move = (TT_Move_Func)Direct_Move; 2521 exc->func_move = (TT_Move_Func)Direct_Move;
2657 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; 2522 exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
2658 2523
2659 if ( CUR.F_dot_P == 0x4000L ) 2524 if ( exc->F_dot_P == 0x4000L )
2660 { 2525 {
2661 if ( CUR.GS.freeVector.x == 0x4000 ) 2526 if ( exc->GS.freeVector.x == 0x4000 )
2662 { 2527 {
2663 CUR.func_move = (TT_Move_Func)Direct_Move_X; 2528 exc->func_move = (TT_Move_Func)Direct_Move_X;
2664 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; 2529 exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
2665 } 2530 }
2666 else if ( CUR.GS.freeVector.y == 0x4000 ) 2531 else if ( exc->GS.freeVector.y == 0x4000 )
2667 { 2532 {
2668 CUR.func_move = (TT_Move_Func)Direct_Move_Y; 2533 exc->func_move = (TT_Move_Func)Direct_Move_Y;
2669 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; 2534 exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
2670 } 2535 }
2671 } 2536 }
2672 2537
2673 /* at small sizes, F_dot_P can become too small, resulting */ 2538 /* at small sizes, F_dot_P can become too small, resulting */
2674 /* in overflows and `spikes' in a number of glyphs like `w'. */ 2539 /* in overflows and `spikes' in a number of glyphs like `w'. */
2675 2540
2676 if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) 2541 if ( FT_ABS( exc->F_dot_P ) < 0x400L )
2677 CUR.F_dot_P = 0x4000L; 2542 exc->F_dot_P = 0x4000L;
2678 2543
2679 /* Disable cached aspect ratio */ 2544 /* Disable cached aspect ratio */
2680 CUR.tt_metrics.ratio = 0; 2545 exc->tt_metrics.ratio = 0;
2681 } 2546 }
2682 2547
2683 2548
2684 /*************************************************************************/ 2549 /*************************************************************************/
2685 /* */ 2550 /* */
2686 /* <Function> */ 2551 /* <Function> */
2687 /* Normalize */ 2552 /* Normalize */
2688 /* */ 2553 /* */
2689 /* <Description> */ 2554 /* <Description> */
2690 /* Norms a vector. */ 2555 /* Norms a vector. */
2691 /* */ 2556 /* */
2692 /* <Input> */ 2557 /* <Input> */
2693 /* Vx :: The horizontal input vector coordinate. */ 2558 /* Vx :: The horizontal input vector coordinate. */
2694 /* Vy :: The vertical input vector coordinate. */ 2559 /* Vy :: The vertical input vector coordinate. */
2695 /* */ 2560 /* */
2696 /* <Output> */ 2561 /* <Output> */
2697 /* R :: The normed unit vector. */ 2562 /* R :: The normed unit vector. */
2698 /* */ 2563 /* */
2699 /* <Return> */ 2564 /* <Return> */
2700 /* Returns FAILURE if a vector parameter is zero. */ 2565 /* Returns FAILURE if a vector parameter is zero. */
2701 /* */ 2566 /* */
2702 /* <Note> */ 2567 /* <Note> */
2703 /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ 2568 /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */
2704 /* R is undefined. */ 2569 /* R is undefined. */
2705 /* */ 2570 /* */
2706 static FT_Bool 2571 static FT_Bool
2707 Normalize( EXEC_OP_ FT_F26Dot6 Vx, 2572 Normalize( FT_F26Dot6 Vx,
2708 FT_F26Dot6 Vy, 2573 FT_F26Dot6 Vy,
2709 FT_UnitVector* R ) 2574 FT_UnitVector* R )
2710 { 2575 {
2711 FT_F26Dot6 W; 2576 FT_Vector V;
2712
2713 FT_UNUSED_EXEC;
2714 2577
2715 2578
2716 if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) 2579 if ( Vx == 0 && Vy == 0 )
2717 { 2580 {
2718 if ( Vx == 0 && Vy == 0 ) 2581 /* XXX: UNDOCUMENTED! It seems that it is possible to try */
2719 { 2582 /* to normalize the vector (0,0). Return immediately. */
2720 /* XXX: UNDOCUMENTED! It seems that it is possible to try */ 2583 return SUCCESS;
2721 /* to normalize the vector (0,0). Return immediately. */
2722 return SUCCESS;
2723 }
2724
2725 Vx *= 0x4000;
2726 Vy *= 0x4000;
2727 } 2584 }
2728 2585
2729 W = FT_Hypot( Vx, Vy ); 2586 V.x = Vx;
2587 V.y = Vy;
2730 2588
2731 R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); 2589 FT_Vector_NormLen( &V );
2732 R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); 2590
2591 R->x = (FT_F2Dot14)( V.x / 4 );
2592 R->y = (FT_F2Dot14)( V.y / 4 );
2733 2593
2734 return SUCCESS; 2594 return SUCCESS;
2735 } 2595 }
2736 2596
2737 2597
2738 /*************************************************************************/ 2598 /*************************************************************************/
2739 /* */ 2599 /* */
2740 /* Here we start with the implementation of the various opcodes. */ 2600 /* Here we start with the implementation of the various opcodes. */
2741 /* */ 2601 /* */
2742 /*************************************************************************/ 2602 /*************************************************************************/
2743 2603
2744 2604
2745 static FT_Bool 2605 #define ARRAY_BOUND_ERROR \
2746 Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, 2606 do \
2747 FT_UShort aIdx2, 2607 { \
2748 FT_Int aOpc, 2608 exc->error = FT_THROW( Invalid_Reference ); \
2749 FT_UnitVector* Vec ) 2609 return; \
2750 { 2610 } while (0)
2751 FT_Long A, B, C; 2611
2752 FT_Vector* p1; 2612
2753 FT_Vector* p2; 2613 /*************************************************************************/
2754 2614 /* */
2755 2615 /* MPPEM[]: Measure Pixel Per EM */
2756 if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || 2616 /* Opcode range: 0x4B */
2757 BOUNDS( aIdx2, CUR.zp1.n_points ) ) 2617 /* Stack: --> Euint16 */
2758 { 2618 /* */
2759 if ( CUR.pedantic_hinting ) 2619 static void
2760 CUR.error = FT_THROW( Invalid_Reference ); 2620 Ins_MPPEM( TT_ExecContext exc,
2761 return FAILURE; 2621 FT_Long* args )
2762 } 2622 {
2763 2623 args[0] = exc->func_cur_ppem( exc );
2764 p1 = CUR.zp1.cur + aIdx2; 2624 }
2765 p2 = CUR.zp2.cur + aIdx1; 2625
2766 2626
2767 A = p1->x - p2->x; 2627 /*************************************************************************/
2768 B = p1->y - p2->y; 2628 /* */
2769 2629 /* MPS[]: Measure Point Size */
2770 /* If p1 == p2, SPVTL and SFVTL behave the same as */ 2630 /* Opcode range: 0x4C */
2771 /* SPVTCA[X] and SFVTCA[X], respectively. */ 2631 /* Stack: --> Euint16 */
2772 /* */ 2632 /* */
2773 /* Confirmed by Greg Hitchcock. */ 2633 static void
2774 2634 Ins_MPS( TT_ExecContext exc,
2775 if ( A == 0 && B == 0 ) 2635 FT_Long* args )
2776 { 2636 {
2777 A = 0x4000; 2637 /* Note: The point size should be irrelevant in a given font program; */
2778 aOpc = 0; 2638 /* we thus decide to return only the PPEM value. */
2779 } 2639 #if 0
2780 2640 args[0] = exc->metrics.pointSize;
2781 if ( ( aOpc & 1 ) != 0 )
2782 {
2783 C = B; /* counter clockwise rotation */
2784 B = A;
2785 A = -C;
2786 }
2787
2788 NORMalize( A, B, Vec );
2789
2790 return SUCCESS;
2791 }
2792
2793
2794 /* When not using the big switch statements, the interpreter uses a */
2795 /* call table defined later below in this source. Each opcode must */
2796 /* thus have a corresponding function, even trivial ones. */
2797 /* */
2798 /* They are all defined there. */
2799
2800 #define DO_SVTCA \
2801 { \
2802 FT_Short A, B; \
2803 \
2804 \
2805 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2806 B = A ^ (FT_Short)0x4000; \
2807 \
2808 CUR.GS.freeVector.x = A; \
2809 CUR.GS.projVector.x = A; \
2810 CUR.GS.dualVector.x = A; \
2811 \
2812 CUR.GS.freeVector.y = B; \
2813 CUR.GS.projVector.y = B; \
2814 CUR.GS.dualVector.y = B; \
2815 \
2816 COMPUTE_Funcs(); \
2817 }
2818
2819
2820 #define DO_SPVTCA \
2821 { \
2822 FT_Short A, B; \
2823 \
2824 \
2825 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2826 B = A ^ (FT_Short)0x4000; \
2827 \
2828 CUR.GS.projVector.x = A; \
2829 CUR.GS.dualVector.x = A; \
2830 \
2831 CUR.GS.projVector.y = B; \
2832 CUR.GS.dualVector.y = B; \
2833 \
2834 GUESS_VECTOR( freeVector ); \
2835 \
2836 COMPUTE_Funcs(); \
2837 }
2838
2839
2840 #define DO_SFVTCA \
2841 { \
2842 FT_Short A, B; \
2843 \
2844 \
2845 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2846 B = A ^ (FT_Short)0x4000; \
2847 \
2848 CUR.GS.freeVector.x = A; \
2849 CUR.GS.freeVector.y = B; \
2850 \
2851 GUESS_VECTOR( projVector ); \
2852 \
2853 COMPUTE_Funcs(); \
2854 }
2855
2856
2857 #define DO_SPVTL \
2858 if ( INS_SxVTL( (FT_UShort)args[1], \
2859 (FT_UShort)args[0], \
2860 CUR.opcode, \
2861 &CUR.GS.projVector ) == SUCCESS ) \
2862 { \
2863 CUR.GS.dualVector = CUR.GS.projVector; \
2864 GUESS_VECTOR( freeVector ); \
2865 COMPUTE_Funcs(); \
2866 }
2867
2868
2869 #define DO_SFVTL \
2870 if ( INS_SxVTL( (FT_UShort)args[1], \
2871 (FT_UShort)args[0], \
2872 CUR.opcode, \
2873 &CUR.GS.freeVector ) == SUCCESS ) \
2874 { \
2875 GUESS_VECTOR( projVector ); \
2876 COMPUTE_Funcs(); \
2877 }
2878
2879
2880 #define DO_SFVTPV \
2881 GUESS_VECTOR( projVector ); \
2882 CUR.GS.freeVector = CUR.GS.projVector; \
2883 COMPUTE_Funcs();
2884
2885
2886 #define DO_SPVFS \
2887 { \
2888 FT_Short S; \
2889 FT_Long X, Y; \
2890 \
2891 \
2892 /* Only use low 16bits, then sign extend */ \
2893 S = (FT_Short)args[1]; \
2894 Y = (FT_Long)S; \
2895 S = (FT_Short)args[0]; \
2896 X = (FT_Long)S; \
2897 \
2898 NORMalize( X, Y, &CUR.GS.projVector ); \
2899 \
2900 CUR.GS.dualVector = CUR.GS.projVector; \
2901 GUESS_VECTOR( freeVector ); \
2902 COMPUTE_Funcs(); \
2903 }
2904
2905
2906 #define DO_SFVFS \
2907 { \
2908 FT_Short S; \
2909 FT_Long X, Y; \
2910 \
2911 \
2912 /* Only use low 16bits, then sign extend */ \
2913 S = (FT_Short)args[1]; \
2914 Y = (FT_Long)S; \
2915 S = (FT_Short)args[0]; \
2916 X = S; \
2917 \
2918 NORMalize( X, Y, &CUR.GS.freeVector ); \
2919 GUESS_VECTOR( projVector ); \
2920 COMPUTE_Funcs(); \
2921 }
2922
2923
2924 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2925 #define DO_GPV \
2926 if ( CUR.face->unpatented_hinting ) \
2927 { \
2928 args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
2929 args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
2930 } \
2931 else \
2932 { \
2933 args[0] = CUR.GS.projVector.x; \
2934 args[1] = CUR.GS.projVector.y; \
2935 }
2936 #else 2641 #else
2937 #define DO_GPV \ 2642 args[0] = exc->func_cur_ppem( exc );
2938 args[0] = CUR.GS.projVector.x; \
2939 args[1] = CUR.GS.projVector.y;
2940 #endif 2643 #endif
2941 2644 }
2942 2645
2943 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 2646
2944 #define DO_GFV \ 2647 /*************************************************************************/
2945 if ( CUR.face->unpatented_hinting ) \ 2648 /* */
2946 { \ 2649 /* DUP[]: DUPlicate the stack's top element */
2947 args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ 2650 /* Opcode range: 0x20 */
2948 args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ 2651 /* Stack: StkElt --> StkElt StkElt */
2949 } \ 2652 /* */
2950 else \ 2653 static void
2951 { \ 2654 Ins_DUP( FT_Long* args )
2952 args[0] = CUR.GS.freeVector.x; \ 2655 {
2953 args[1] = CUR.GS.freeVector.y; \
2954 }
2955 #else
2956 #define DO_GFV \
2957 args[0] = CUR.GS.freeVector.x; \
2958 args[1] = CUR.GS.freeVector.y;
2959 #endif
2960
2961
2962 #define DO_SRP0 \
2963 CUR.GS.rp0 = (FT_UShort)args[0];
2964
2965
2966 #define DO_SRP1 \
2967 CUR.GS.rp1 = (FT_UShort)args[0];
2968
2969
2970 #define DO_SRP2 \
2971 CUR.GS.rp2 = (FT_UShort)args[0];
2972
2973
2974 #define DO_RTHG \
2975 CUR.GS.round_state = TT_Round_To_Half_Grid; \
2976 CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
2977
2978
2979 #define DO_RTG \
2980 CUR.GS.round_state = TT_Round_To_Grid; \
2981 CUR.func_round = (TT_Round_Func)Round_To_Grid;
2982
2983
2984 #define DO_RTDG \
2985 CUR.GS.round_state = TT_Round_To_Double_Grid; \
2986 CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
2987
2988
2989 #define DO_RUTG \
2990 CUR.GS.round_state = TT_Round_Up_To_Grid; \
2991 CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
2992
2993
2994 #define DO_RDTG \
2995 CUR.GS.round_state = TT_Round_Down_To_Grid; \
2996 CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
2997
2998
2999 #define DO_ROFF \
3000 CUR.GS.round_state = TT_Round_Off; \
3001 CUR.func_round = (TT_Round_Func)Round_None;
3002
3003
3004 #define DO_SROUND \
3005 SET_SuperRound( 0x4000, args[0] ); \
3006 CUR.GS.round_state = TT_Round_Super; \
3007 CUR.func_round = (TT_Round_Func)Round_Super;
3008
3009
3010 #define DO_S45ROUND \
3011 SET_SuperRound( 0x2D41, args[0] ); \
3012 CUR.GS.round_state = TT_Round_Super_45; \
3013 CUR.func_round = (TT_Round_Func)Round_Super_45;
3014
3015
3016 #define DO_SLOOP \
3017 if ( args[0] < 0 ) \
3018 CUR.error = FT_THROW( Bad_Argument ); \
3019 else \
3020 CUR.GS.loop = args[0];
3021
3022
3023 #define DO_SMD \
3024 CUR.GS.minimum_distance = args[0];
3025
3026
3027 #define DO_SCVTCI \
3028 CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
3029
3030
3031 #define DO_SSWCI \
3032 CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
3033
3034
3035 #define DO_SSW \
3036 CUR.GS.single_width_value = FT_MulFix( args[0], \
3037 CUR.tt_metrics.scale );
3038
3039
3040 #define DO_FLIPON \
3041 CUR.GS.auto_flip = TRUE;
3042
3043
3044 #define DO_FLIPOFF \
3045 CUR.GS.auto_flip = FALSE;
3046
3047
3048 #define DO_SDB \
3049 CUR.GS.delta_base = (FT_UShort)args[0];
3050
3051
3052 #define DO_SDS \
3053 if ( (FT_ULong)args[0] > 6UL ) \
3054 CUR.error = FT_THROW( Bad_Argument ); \
3055 else \
3056 CUR.GS.delta_shift = (FT_UShort)args[0];
3057
3058
3059 #define DO_MD /* nothing */
3060
3061
3062 #define DO_MPPEM \
3063 args[0] = CUR_Func_cur_ppem();
3064
3065
3066 /* Note: The pointSize should be irrelevant in a given font program; */
3067 /* we thus decide to return only the ppem. */
3068 #if 0
3069
3070 #define DO_MPS \
3071 args[0] = CUR.metrics.pointSize;
3072
3073 #else
3074
3075 #define DO_MPS \
3076 args[0] = CUR_Func_cur_ppem();
3077
3078 #endif /* 0 */
3079
3080
3081 #define DO_DUP \
3082 args[1] = args[0]; 2656 args[1] = args[0];
3083 2657 }
3084 2658
3085 #define DO_CLEAR \ 2659
3086 CUR.new_top = 0; 2660 /*************************************************************************/
3087 2661 /* */
3088 2662 /* POP[]: POP the stack's top element */
3089 #define DO_SWAP \ 2663 /* Opcode range: 0x21 */
3090 { \ 2664 /* Stack: StkElt --> */
3091 FT_Long L; \ 2665 /* */
3092 \ 2666 static void
3093 \ 2667 Ins_POP( void )
3094 L = args[0]; \ 2668 {
3095 args[0] = args[1]; \ 2669 /* nothing to do */
3096 args[1] = L; \ 2670 }
3097 } 2671
3098 2672
3099 2673 /*************************************************************************/
3100 #define DO_DEPTH \ 2674 /* */
3101 args[0] = CUR.top; 2675 /* CLEAR[]: CLEAR the entire stack */
3102 2676 /* Opcode range: 0x22 */
3103 2677 /* Stack: StkElt... --> */
3104 #define DO_CINDEX \ 2678 /* */
3105 { \ 2679 static void
3106 FT_Long L; \ 2680 Ins_CLEAR( TT_ExecContext exc )
3107 \ 2681 {
3108 \ 2682 exc->new_top = 0;
3109 L = args[0]; \ 2683 }
3110 \ 2684
3111 if ( L <= 0 || L > CUR.args ) \ 2685
3112 { \ 2686 /*************************************************************************/
3113 if ( CUR.pedantic_hinting ) \ 2687 /* */
3114 CUR.error = FT_THROW( Invalid_Reference ); \ 2688 /* SWAP[]: SWAP the stack's top two elements */
3115 args[0] = 0; \ 2689 /* Opcode range: 0x23 */
3116 } \ 2690 /* Stack: 2 * StkElt --> 2 * StkElt */
3117 else \ 2691 /* */
3118 args[0] = CUR.stack[CUR.args - L]; \ 2692 static void
3119 } 2693 Ins_SWAP( FT_Long* args )
3120 2694 {
3121 2695 FT_Long L;
3122 #define DO_JROT \ 2696
3123 if ( args[1] != 0 ) \ 2697
3124 { \ 2698 L = args[0];
3125 if ( args[0] == 0 && CUR.args == 0 ) \ 2699 args[0] = args[1];
3126 CUR.error = FT_THROW( Bad_Argument ); \ 2700 args[1] = L;
3127 CUR.IP += args[0]; \ 2701 }
3128 if ( CUR.IP < 0 || \ 2702
3129 ( CUR.callTop > 0 && \ 2703
3130 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \ 2704 /*************************************************************************/
3131 CUR.error = FT_THROW( Bad_Argument ); \ 2705 /* */
3132 CUR.step_ins = FALSE; \ 2706 /* DEPTH[]: return the stack DEPTH */
3133 } 2707 /* Opcode range: 0x24 */
3134 2708 /* Stack: --> uint32 */
3135 2709 /* */
3136 #define DO_JMPR \ 2710 static void
3137 if ( args[0] == 0 && CUR.args == 0 ) \ 2711 Ins_DEPTH( TT_ExecContext exc,
3138 CUR.error = FT_THROW( Bad_Argument ); \ 2712 FT_Long* args )
3139 CUR.IP += args[0]; \ 2713 {
3140 if ( CUR.IP < 0 || \ 2714 args[0] = exc->top;
3141 ( CUR.callTop > 0 && \ 2715 }
3142 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \ 2716
3143 CUR.error = FT_THROW( Bad_Argument ); \ 2717
3144 CUR.step_ins = FALSE; 2718 /*************************************************************************/
3145 2719 /* */
3146 2720 /* LT[]: Less Than */
3147 #define DO_JROF \ 2721 /* Opcode range: 0x50 */
3148 if ( args[1] == 0 ) \ 2722 /* Stack: int32? int32? --> bool */
3149 { \ 2723 /* */
3150 if ( args[0] == 0 && CUR.args == 0 ) \ 2724 static void
3151 CUR.error = FT_THROW( Bad_Argument ); \ 2725 Ins_LT( FT_Long* args )
3152 CUR.IP += args[0]; \ 2726 {
3153 if ( CUR.IP < 0 || \
3154 ( CUR.callTop > 0 && \
3155 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
3156 CUR.error = FT_THROW( Bad_Argument ); \
3157 CUR.step_ins = FALSE; \
3158 }
3159
3160
3161 #define DO_LT \
3162 args[0] = ( args[0] < args[1] ); 2727 args[0] = ( args[0] < args[1] );
3163 2728 }
3164 2729
3165 #define DO_LTEQ \ 2730
2731 /*************************************************************************/
2732 /* */
2733 /* LTEQ[]: Less Than or EQual */
2734 /* Opcode range: 0x51 */
2735 /* Stack: int32? int32? --> bool */
2736 /* */
2737 static void
2738 Ins_LTEQ( FT_Long* args )
2739 {
3166 args[0] = ( args[0] <= args[1] ); 2740 args[0] = ( args[0] <= args[1] );
3167 2741 }
3168 2742
3169 #define DO_GT \ 2743
2744 /*************************************************************************/
2745 /* */
2746 /* GT[]: Greater Than */
2747 /* Opcode range: 0x52 */
2748 /* Stack: int32? int32? --> bool */
2749 /* */
2750 static void
2751 Ins_GT( FT_Long* args )
2752 {
3170 args[0] = ( args[0] > args[1] ); 2753 args[0] = ( args[0] > args[1] );
3171 2754 }
3172 2755
3173 #define DO_GTEQ \ 2756
2757 /*************************************************************************/
2758 /* */
2759 /* GTEQ[]: Greater Than or EQual */
2760 /* Opcode range: 0x53 */
2761 /* Stack: int32? int32? --> bool */
2762 /* */
2763 static void
2764 Ins_GTEQ( FT_Long* args )
2765 {
3174 args[0] = ( args[0] >= args[1] ); 2766 args[0] = ( args[0] >= args[1] );
3175 2767 }
3176 2768
3177 #define DO_EQ \ 2769
2770 /*************************************************************************/
2771 /* */
2772 /* EQ[]: EQual */
2773 /* Opcode range: 0x54 */
2774 /* Stack: StkElt StkElt --> bool */
2775 /* */
2776 static void
2777 Ins_EQ( FT_Long* args )
2778 {
3178 args[0] = ( args[0] == args[1] ); 2779 args[0] = ( args[0] == args[1] );
3179 2780 }
3180 2781
3181 #define DO_NEQ \ 2782
2783 /*************************************************************************/
2784 /* */
2785 /* NEQ[]: Not EQual */
2786 /* Opcode range: 0x55 */
2787 /* Stack: StkElt StkElt --> bool */
2788 /* */
2789 static void
2790 Ins_NEQ( FT_Long* args )
2791 {
3182 args[0] = ( args[0] != args[1] ); 2792 args[0] = ( args[0] != args[1] );
3183 2793 }
3184 2794
3185 #define DO_ODD \ 2795
3186 args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); 2796 /*************************************************************************/
3187 2797 /* */
3188 2798 /* ODD[]: Is ODD */
3189 #define DO_EVEN \ 2799 /* Opcode range: 0x56 */
3190 args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); 2800 /* Stack: f26.6 --> bool */
3191 2801 /* */
3192 2802 static void
3193 #define DO_AND \ 2803 Ins_ODD( TT_ExecContext exc,
2804 FT_Long* args )
2805 {
2806 args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
2807 }
2808
2809
2810 /*************************************************************************/
2811 /* */
2812 /* EVEN[]: Is EVEN */
2813 /* Opcode range: 0x57 */
2814 /* Stack: f26.6 --> bool */
2815 /* */
2816 static void
2817 Ins_EVEN( TT_ExecContext exc,
2818 FT_Long* args )
2819 {
2820 args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
2821 }
2822
2823
2824 /*************************************************************************/
2825 /* */
2826 /* AND[]: logical AND */
2827 /* Opcode range: 0x5A */
2828 /* Stack: uint32 uint32 --> uint32 */
2829 /* */
2830 static void
2831 Ins_AND( FT_Long* args )
2832 {
3194 args[0] = ( args[0] && args[1] ); 2833 args[0] = ( args[0] && args[1] );
3195 2834 }
3196 2835
3197 #define DO_OR \ 2836
2837 /*************************************************************************/
2838 /* */
2839 /* OR[]: logical OR */
2840 /* Opcode range: 0x5B */
2841 /* Stack: uint32 uint32 --> uint32 */
2842 /* */
2843 static void
2844 Ins_OR( FT_Long* args )
2845 {
3198 args[0] = ( args[0] || args[1] ); 2846 args[0] = ( args[0] || args[1] );
3199 2847 }
3200 2848
3201 #define DO_NOT \ 2849
2850 /*************************************************************************/
2851 /* */
2852 /* NOT[]: logical NOT */
2853 /* Opcode range: 0x5C */
2854 /* Stack: StkElt --> uint32 */
2855 /* */
2856 static void
2857 Ins_NOT( FT_Long* args )
2858 {
3202 args[0] = !args[0]; 2859 args[0] = !args[0];
3203 2860 }
3204 2861
3205 #define DO_ADD \ 2862
2863 /*************************************************************************/
2864 /* */
2865 /* ADD[]: ADD */
2866 /* Opcode range: 0x60 */
2867 /* Stack: f26.6 f26.6 --> f26.6 */
2868 /* */
2869 static void
2870 Ins_ADD( FT_Long* args )
2871 {
3206 args[0] += args[1]; 2872 args[0] += args[1];
3207 2873 }
3208 2874
3209 #define DO_SUB \ 2875
2876 /*************************************************************************/
2877 /* */
2878 /* SUB[]: SUBtract */
2879 /* Opcode range: 0x61 */
2880 /* Stack: f26.6 f26.6 --> f26.6 */
2881 /* */
2882 static void
2883 Ins_SUB( FT_Long* args )
2884 {
3210 args[0] -= args[1]; 2885 args[0] -= args[1];
3211 2886 }
3212 2887
3213 #define DO_DIV \ 2888
3214 if ( args[1] == 0 ) \ 2889 /*************************************************************************/
3215 CUR.error = FT_THROW( Divide_By_Zero ); \ 2890 /* */
3216 else \ 2891 /* DIV[]: DIVide */
2892 /* Opcode range: 0x62 */
2893 /* Stack: f26.6 f26.6 --> f26.6 */
2894 /* */
2895 static void
2896 Ins_DIV( TT_ExecContext exc,
2897 FT_Long* args )
2898 {
2899 if ( args[1] == 0 )
2900 exc->error = FT_THROW( Divide_By_Zero );
2901 else
3217 args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); 2902 args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
3218 2903 }
3219 2904
3220 #define DO_MUL \ 2905
2906 /*************************************************************************/
2907 /* */
2908 /* MUL[]: MULtiply */
2909 /* Opcode range: 0x63 */
2910 /* Stack: f26.6 f26.6 --> f26.6 */
2911 /* */
2912 static void
2913 Ins_MUL( FT_Long* args )
2914 {
3221 args[0] = FT_MulDiv( args[0], args[1], 64L ); 2915 args[0] = FT_MulDiv( args[0], args[1], 64L );
3222 2916 }
3223 2917
3224 #define DO_ABS \ 2918
2919 /*************************************************************************/
2920 /* */
2921 /* ABS[]: ABSolute value */
2922 /* Opcode range: 0x64 */
2923 /* Stack: f26.6 --> f26.6 */
2924 /* */
2925 static void
2926 Ins_ABS( FT_Long* args )
2927 {
3225 args[0] = FT_ABS( args[0] ); 2928 args[0] = FT_ABS( args[0] );
3226 2929 }
3227 2930
3228 #define DO_NEG \ 2931
2932 /*************************************************************************/
2933 /* */
2934 /* NEG[]: NEGate */
2935 /* Opcode range: 0x65 */
2936 /* Stack: f26.6 --> f26.6 */
2937 /* */
2938 static void
2939 Ins_NEG( FT_Long* args )
2940 {
3229 args[0] = -args[0]; 2941 args[0] = -args[0];
3230 2942 }
3231 2943
3232 #define DO_FLOOR \ 2944
2945 /*************************************************************************/
2946 /* */
2947 /* FLOOR[]: FLOOR */
2948 /* Opcode range: 0x66 */
2949 /* Stack: f26.6 --> f26.6 */
2950 /* */
2951 static void
2952 Ins_FLOOR( FT_Long* args )
2953 {
3233 args[0] = FT_PIX_FLOOR( args[0] ); 2954 args[0] = FT_PIX_FLOOR( args[0] );
3234 2955 }
3235 2956
3236 #define DO_CEILING \ 2957
2958 /*************************************************************************/
2959 /* */
2960 /* CEILING[]: CEILING */
2961 /* Opcode range: 0x67 */
2962 /* Stack: f26.6 --> f26.6 */
2963 /* */
2964 static void
2965 Ins_CEILING( FT_Long* args )
2966 {
3237 args[0] = FT_PIX_CEIL( args[0] ); 2967 args[0] = FT_PIX_CEIL( args[0] );
3238 2968 }
2969
2970
2971 /*************************************************************************/
2972 /* */
2973 /* RS[]: Read Store */
2974 /* Opcode range: 0x43 */
2975 /* Stack: uint32 --> uint32 */
2976 /* */
2977 static void
2978 Ins_RS( TT_ExecContext exc,
2979 FT_Long* args )
2980 {
3239 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 2981 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3240 2982
3241 #define DO_RS \ 2983 FT_ULong I = (FT_ULong)args[0];
3242 { \ 2984
3243 FT_ULong I = (FT_ULong)args[0]; \ 2985
3244 \ 2986 if ( BOUNDSL( I, exc->storeSize ) )
3245 \ 2987 {
3246 if ( BOUNDSL( I, CUR.storeSize ) ) \ 2988 if ( exc->pedantic_hinting )
3247 { \ 2989 ARRAY_BOUND_ERROR;
3248 if ( CUR.pedantic_hinting ) \ 2990 else
3249 ARRAY_BOUND_ERROR; \ 2991 args[0] = 0;
3250 else \ 2992 }
3251 args[0] = 0; \ 2993 else
3252 } \ 2994 {
3253 else \ 2995 /* subpixel hinting - avoid Typeman Dstroke and */
3254 { \ 2996 /* IStroke and Vacuform rounds */
3255 /* subpixel hinting - avoid Typeman Dstroke and */ \ 2997 if ( SUBPIXEL_HINTING &&
3256 /* IStroke and Vacuform rounds */ \ 2998 exc->ignore_x_mode &&
3257 \ 2999 ( ( I == 24 &&
3258 if ( SUBPIXEL_HINTING && \ 3000 ( exc->face->sph_found_func_flags &
3259 CUR.ignore_x_mode && \ 3001 ( SPH_FDEF_SPACING_1 |
3260 ( ( I == 24 && \ 3002 SPH_FDEF_SPACING_2 ) ) ) ||
3261 ( CUR.face->sph_found_func_flags & \ 3003 ( I == 22 &&
3262 ( SPH_FDEF_SPACING_1 | \ 3004 ( exc->sph_in_func_flags &
3263 SPH_FDEF_SPACING_2 ) ) ) || \ 3005 SPH_FDEF_TYPEMAN_STROKES ) ) ||
3264 ( I == 22 && \ 3006 ( I == 8 &&
3265 ( CUR.sph_in_func_flags & \ 3007 ( exc->face->sph_found_func_flags &
3266 SPH_FDEF_TYPEMAN_STROKES ) ) || \ 3008 SPH_FDEF_VACUFORM_ROUND_1 ) &&
3267 ( I == 8 && \ 3009 exc->iup_called ) ) )
3268 ( CUR.face->sph_found_func_flags & \ 3010 args[0] = 0;
3269 SPH_FDEF_VACUFORM_ROUND_1 ) && \ 3011 else
3270 CUR.iup_called ) ) ) \ 3012 args[0] = exc->storage[I];
3271 args[0] = 0; \ 3013 }
3272 else \
3273 args[0] = CUR.storage[I]; \
3274 } \
3275 }
3276 3014
3277 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3015 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3278 3016
3279 #define DO_RS \ 3017 FT_ULong I = (FT_ULong)args[0];
3280 { \ 3018
3281 FT_ULong I = (FT_ULong)args[0]; \ 3019
3282 \ 3020 if ( BOUNDSL( I, exc->storeSize ) )
3283 \ 3021 {
3284 if ( BOUNDSL( I, CUR.storeSize ) ) \ 3022 if ( exc->pedantic_hinting )
3285 { \ 3023 ARRAY_BOUND_ERROR;
3286 if ( CUR.pedantic_hinting ) \ 3024 else
3287 { \ 3025 args[0] = 0;
3288 ARRAY_BOUND_ERROR; \ 3026 }
3289 } \ 3027 else
3290 else \ 3028 args[0] = exc->storage[I];
3291 args[0] = 0; \
3292 } \
3293 else \
3294 args[0] = CUR.storage[I]; \
3295 }
3296 3029
3297 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3030 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3298 3031 }
3299 3032
3300 #define DO_WS \ 3033
3301 { \ 3034 /*************************************************************************/
3302 FT_ULong I = (FT_ULong)args[0]; \ 3035 /* */
3303 \ 3036 /* WS[]: Write Store */
3304 \ 3037 /* Opcode range: 0x42 */
3305 if ( BOUNDSL( I, CUR.storeSize ) ) \ 3038 /* Stack: uint32 uint32 --> */
3306 { \ 3039 /* */
3307 if ( CUR.pedantic_hinting ) \ 3040 static void
3308 { \ 3041 Ins_WS( TT_ExecContext exc,
3309 ARRAY_BOUND_ERROR; \ 3042 FT_Long* args )
3310 } \ 3043 {
3311 } \ 3044 FT_ULong I = (FT_ULong)args[0];
3312 else \ 3045
3313 CUR.storage[I] = args[1]; \ 3046
3314 } 3047 if ( BOUNDSL( I, exc->storeSize ) )
3315 3048 {
3316 3049 if ( exc->pedantic_hinting )
3317 #define DO_RCVT \ 3050 ARRAY_BOUND_ERROR;
3318 { \ 3051 }
3319 FT_ULong I = (FT_ULong)args[0]; \ 3052 else
3320 \ 3053 exc->storage[I] = args[1];
3321 \ 3054 }
3322 if ( BOUNDSL( I, CUR.cvtSize ) ) \ 3055
3323 { \ 3056
3324 if ( CUR.pedantic_hinting ) \ 3057 /*************************************************************************/
3325 { \ 3058 /* */
3326 ARRAY_BOUND_ERROR; \ 3059 /* WCVTP[]: Write CVT in Pixel units */
3327 } \ 3060 /* Opcode range: 0x44 */
3328 else \ 3061 /* Stack: f26.6 uint32 --> */
3329 args[0] = 0; \ 3062 /* */
3330 } \ 3063 static void
3331 else \ 3064 Ins_WCVTP( TT_ExecContext exc,
3332 args[0] = CUR_Func_read_cvt( I ); \ 3065 FT_Long* args )
3333 } 3066 {
3334 3067 FT_ULong I = (FT_ULong)args[0];
3335 3068
3336 #define DO_WCVTP \ 3069
3337 { \ 3070 if ( BOUNDSL( I, exc->cvtSize ) )
3338 FT_ULong I = (FT_ULong)args[0]; \ 3071 {
3339 \ 3072 if ( exc->pedantic_hinting )
3340 \ 3073 ARRAY_BOUND_ERROR;
3341 if ( BOUNDSL( I, CUR.cvtSize ) ) \ 3074 }
3342 { \ 3075 else
3343 if ( CUR.pedantic_hinting ) \ 3076 exc->func_write_cvt( exc, I, args[1] );
3344 { \ 3077 }
3345 ARRAY_BOUND_ERROR; \ 3078
3346 } \ 3079
3347 } \ 3080 /*************************************************************************/
3348 else \ 3081 /* */
3349 CUR_Func_write_cvt( I, args[1] ); \ 3082 /* WCVTF[]: Write CVT in Funits */
3350 } 3083 /* Opcode range: 0x70 */
3351 3084 /* Stack: uint32 uint32 --> */
3352 3085 /* */
3353 #define DO_WCVTF \ 3086 static void
3354 { \ 3087 Ins_WCVTF( TT_ExecContext exc,
3355 FT_ULong I = (FT_ULong)args[0]; \ 3088 FT_Long* args )
3356 \ 3089 {
3357 \ 3090 FT_ULong I = (FT_ULong)args[0];
3358 if ( BOUNDSL( I, CUR.cvtSize ) ) \ 3091
3359 { \ 3092
3360 if ( CUR.pedantic_hinting ) \ 3093 if ( BOUNDSL( I, exc->cvtSize ) )
3361 { \ 3094 {
3362 ARRAY_BOUND_ERROR; \ 3095 if ( exc->pedantic_hinting )
3363 } \ 3096 ARRAY_BOUND_ERROR;
3364 } \ 3097 }
3365 else \ 3098 else
3366 CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ 3099 exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale );
3367 } 3100 }
3368 3101
3369 3102
3370 #define DO_DEBUG \ 3103 /*************************************************************************/
3371 CUR.error = FT_THROW( Debug_OpCode ); 3104 /* */
3372 3105 /* RCVT[]: Read CVT */
3373 3106 /* Opcode range: 0x45 */
3374 #define DO_ROUND \ 3107 /* Stack: uint32 --> f26.6 */
3375 args[0] = CUR_Func_round( \ 3108 /* */
3376 args[0], \ 3109 static void
3377 CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); 3110 Ins_RCVT( TT_ExecContext exc,
3378 3111 FT_Long* args )
3379 3112 {
3380 #define DO_NROUND \ 3113 FT_ULong I = (FT_ULong)args[0];
3381 args[0] = ROUND_None( args[0], \ 3114
3382 CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); 3115
3383 3116 if ( BOUNDSL( I, exc->cvtSize ) )
3384 3117 {
3385 #define DO_MAX \ 3118 if ( exc->pedantic_hinting )
3386 if ( args[1] > args[0] ) \ 3119 ARRAY_BOUND_ERROR;
3120 else
3121 args[0] = 0;
3122 }
3123 else
3124 args[0] = exc->func_read_cvt( exc, I );
3125 }
3126
3127
3128 /*************************************************************************/
3129 /* */
3130 /* AA[]: Adjust Angle */
3131 /* Opcode range: 0x7F */
3132 /* Stack: uint32 --> */
3133 /* */
3134 static void
3135 Ins_AA( void )
3136 {
3137 /* intentionally no longer supported */
3138 }
3139
3140
3141 /*************************************************************************/
3142 /* */
3143 /* DEBUG[]: DEBUG. Unsupported. */
3144 /* Opcode range: 0x4F */
3145 /* Stack: uint32 --> */
3146 /* */
3147 /* Note: The original instruction pops a value from the stack. */
3148 /* */
3149 static void
3150 Ins_DEBUG( TT_ExecContext exc )
3151 {
3152 exc->error = FT_THROW( Debug_OpCode );
3153 }
3154
3155
3156 /*************************************************************************/
3157 /* */
3158 /* ROUND[ab]: ROUND value */
3159 /* Opcode range: 0x68-0x6B */
3160 /* Stack: f26.6 --> f26.6 */
3161 /* */
3162 static void
3163 Ins_ROUND( TT_ExecContext exc,
3164 FT_Long* args )
3165 {
3166 args[0] = exc->func_round(
3167 exc,
3168 args[0],
3169 exc->tt_metrics.compensations[exc->opcode - 0x68] );
3170 }
3171
3172
3173 /*************************************************************************/
3174 /* */
3175 /* NROUND[ab]: No ROUNDing of value */
3176 /* Opcode range: 0x6C-0x6F */
3177 /* Stack: f26.6 --> f26.6 */
3178 /* */
3179 static void
3180 Ins_NROUND( TT_ExecContext exc,
3181 FT_Long* args )
3182 {
3183 args[0] = Round_None(
3184 exc,
3185 args[0],
3186 exc->tt_metrics.compensations[exc->opcode - 0x6C] );
3187 }
3188
3189
3190 /*************************************************************************/
3191 /* */
3192 /* MAX[]: MAXimum */
3193 /* Opcode range: 0x68 */
3194 /* Stack: int32? int32? --> int32 */
3195 /* */
3196 static void
3197 Ins_MAX( FT_Long* args )
3198 {
3199 if ( args[1] > args[0] )
3387 args[0] = args[1]; 3200 args[0] = args[1];
3388 3201 }
3389 3202
3390 #define DO_MIN \ 3203
3391 if ( args[1] < args[0] ) \ 3204 /*************************************************************************/
3205 /* */
3206 /* MIN[]: MINimum */
3207 /* Opcode range: 0x69 */
3208 /* Stack: int32? int32? --> int32 */
3209 /* */
3210 static void
3211 Ins_MIN( FT_Long* args )
3212 {
3213 if ( args[1] < args[0] )
3392 args[0] = args[1]; 3214 args[0] = args[1];
3393 3215 }
3394 3216
3395 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH 3217
3396 3218 /*************************************************************************/
3397 3219 /* */
3398 #undef ARRAY_BOUND_ERROR 3220 /* MINDEX[]: Move INDEXed element */
3399 #define ARRAY_BOUND_ERROR \ 3221 /* Opcode range: 0x26 */
3400 { \ 3222 /* Stack: int32? --> StkElt */
3401 CUR.error = FT_THROW( Invalid_Reference ); \ 3223 /* */
3402 return; \ 3224 static void
3403 } 3225 Ins_MINDEX( TT_ExecContext exc,
3404 3226 FT_Long* args )
3405 3227 {
3406 /*************************************************************************/ 3228 FT_Long L, K;
3407 /* */ 3229
3408 /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ 3230
3409 /* Opcode range: 0x00-0x01 */ 3231 L = args[0];
3410 /* Stack: --> */ 3232
3411 /* */ 3233 if ( L <= 0 || L > exc->args )
3412 static void 3234 {
3413 Ins_SVTCA( INS_ARG ) 3235 if ( exc->pedantic_hinting )
3414 { 3236 exc->error = FT_THROW( Invalid_Reference );
3415 DO_SVTCA 3237 }
3416 } 3238 else
3417 3239 {
3418 3240 K = exc->stack[exc->args - L];
3419 /*************************************************************************/ 3241
3420 /* */ 3242 FT_ARRAY_MOVE( &exc->stack[exc->args - L ],
3421 /* SPVTCA[a]: Set PVector to Coordinate Axis */ 3243 &exc->stack[exc->args - L + 1],
3422 /* Opcode range: 0x02-0x03 */ 3244 ( L - 1 ) );
3423 /* Stack: --> */ 3245
3424 /* */ 3246 exc->stack[exc->args - 1] = K;
3425 static void 3247 }
3426 Ins_SPVTCA( INS_ARG ) 3248 }
3427 { 3249
3428 DO_SPVTCA 3250
3429 } 3251 /*************************************************************************/
3430 3252 /* */
3431 3253 /* CINDEX[]: Copy INDEXed element */
3432 /*************************************************************************/ 3254 /* Opcode range: 0x25 */
3433 /* */ 3255 /* Stack: int32 --> StkElt */
3434 /* SFVTCA[a]: Set FVector to Coordinate Axis */ 3256 /* */
3435 /* Opcode range: 0x04-0x05 */ 3257 static void
3436 /* Stack: --> */ 3258 Ins_CINDEX( TT_ExecContext exc,
3437 /* */ 3259 FT_Long* args )
3438 static void 3260 {
3439 Ins_SFVTCA( INS_ARG ) 3261 FT_Long L;
3440 { 3262
3441 DO_SFVTCA 3263
3442 } 3264 L = args[0];
3443 3265
3444 3266 if ( L <= 0 || L > exc->args )
3445 /*************************************************************************/ 3267 {
3446 /* */ 3268 if ( exc->pedantic_hinting )
3447 /* SPVTL[a]: Set PVector To Line */ 3269 exc->error = FT_THROW( Invalid_Reference );
3448 /* Opcode range: 0x06-0x07 */ 3270 args[0] = 0;
3449 /* Stack: uint32 uint32 --> */ 3271 }
3450 /* */ 3272 else
3451 static void 3273 args[0] = exc->stack[exc->args - L];
3452 Ins_SPVTL( INS_ARG ) 3274 }
3453 { 3275
3454 DO_SPVTL 3276
3455 } 3277 /*************************************************************************/
3456 3278 /* */
3457 3279 /* ROLL[]: ROLL top three elements */
3458 /*************************************************************************/ 3280 /* Opcode range: 0x8A */
3459 /* */ 3281 /* Stack: 3 * StkElt --> 3 * StkElt */
3460 /* SFVTL[a]: Set FVector To Line */ 3282 /* */
3461 /* Opcode range: 0x08-0x09 */ 3283 static void
3462 /* Stack: uint32 uint32 --> */ 3284 Ins_ROLL( FT_Long* args )
3463 /* */ 3285 {
3464 static void 3286 FT_Long A, B, C;
3465 Ins_SFVTL( INS_ARG ) 3287
3466 { 3288
3467 DO_SFVTL 3289 A = args[2];
3468 } 3290 B = args[1];
3469 3291 C = args[0];
3470 3292
3471 /*************************************************************************/ 3293 args[2] = C;
3472 /* */ 3294 args[1] = A;
3473 /* SFVTPV[]: Set FVector To PVector */ 3295 args[0] = B;
3474 /* Opcode range: 0x0E */ 3296 }
3475 /* Stack: --> */ 3297
3476 /* */ 3298
3477 static void 3299 /*************************************************************************/
3478 Ins_SFVTPV( INS_ARG ) 3300 /* */
3479 { 3301 /* MANAGING THE FLOW OF CONTROL */
3480 DO_SFVTPV 3302 /* */
3481 } 3303 /*************************************************************************/
3482
3483
3484 /*************************************************************************/
3485 /* */
3486 /* SPVFS[]: Set PVector From Stack */
3487 /* Opcode range: 0x0A */
3488 /* Stack: f2.14 f2.14 --> */
3489 /* */
3490 static void
3491 Ins_SPVFS( INS_ARG )
3492 {
3493 DO_SPVFS
3494 }
3495
3496
3497 /*************************************************************************/
3498 /* */
3499 /* SFVFS[]: Set FVector From Stack */
3500 /* Opcode range: 0x0B */
3501 /* Stack: f2.14 f2.14 --> */
3502 /* */
3503 static void
3504 Ins_SFVFS( INS_ARG )
3505 {
3506 DO_SFVFS
3507 }
3508
3509
3510 /*************************************************************************/
3511 /* */
3512 /* GPV[]: Get Projection Vector */
3513 /* Opcode range: 0x0C */
3514 /* Stack: ef2.14 --> ef2.14 */
3515 /* */
3516 static void
3517 Ins_GPV( INS_ARG )
3518 {
3519 DO_GPV
3520 }
3521
3522
3523 /*************************************************************************/
3524 /* GFV[]: Get Freedom Vector */
3525 /* Opcode range: 0x0D */
3526 /* Stack: ef2.14 --> ef2.14 */
3527 /* */
3528 static void
3529 Ins_GFV( INS_ARG )
3530 {
3531 DO_GFV
3532 }
3533
3534
3535 /*************************************************************************/
3536 /* */
3537 /* SRP0[]: Set Reference Point 0 */
3538 /* Opcode range: 0x10 */
3539 /* Stack: uint32 --> */
3540 /* */
3541 static void
3542 Ins_SRP0( INS_ARG )
3543 {
3544 DO_SRP0
3545 }
3546
3547
3548 /*************************************************************************/
3549 /* */
3550 /* SRP1[]: Set Reference Point 1 */
3551 /* Opcode range: 0x11 */
3552 /* Stack: uint32 --> */
3553 /* */
3554 static void
3555 Ins_SRP1( INS_ARG )
3556 {
3557 DO_SRP1
3558 }
3559
3560
3561 /*************************************************************************/
3562 /* */
3563 /* SRP2[]: Set Reference Point 2 */
3564 /* Opcode range: 0x12 */
3565 /* Stack: uint32 --> */
3566 /* */
3567 static void
3568 Ins_SRP2( INS_ARG )
3569 {
3570 DO_SRP2
3571 }
3572
3573
3574 /*************************************************************************/
3575 /* */
3576 /* RTHG[]: Round To Half Grid */
3577 /* Opcode range: 0x19 */
3578 /* Stack: --> */
3579 /* */
3580 static void
3581 Ins_RTHG( INS_ARG )
3582 {
3583 DO_RTHG
3584 }
3585
3586
3587 /*************************************************************************/
3588 /* */
3589 /* RTG[]: Round To Grid */
3590 /* Opcode range: 0x18 */
3591 /* Stack: --> */
3592 /* */
3593 static void
3594 Ins_RTG( INS_ARG )
3595 {
3596 DO_RTG
3597 }
3598
3599
3600 /*************************************************************************/
3601 /* RTDG[]: Round To Double Grid */
3602 /* Opcode range: 0x3D */
3603 /* Stack: --> */
3604 /* */
3605 static void
3606 Ins_RTDG( INS_ARG )
3607 {
3608 DO_RTDG
3609 }
3610
3611
3612 /*************************************************************************/
3613 /* RUTG[]: Round Up To Grid */
3614 /* Opcode range: 0x7C */
3615 /* Stack: --> */
3616 /* */
3617 static void
3618 Ins_RUTG( INS_ARG )
3619 {
3620 DO_RUTG
3621 }
3622
3623
3624 /*************************************************************************/
3625 /* */
3626 /* RDTG[]: Round Down To Grid */
3627 /* Opcode range: 0x7D */
3628 /* Stack: --> */
3629 /* */
3630 static void
3631 Ins_RDTG( INS_ARG )
3632 {
3633 DO_RDTG
3634 }
3635
3636
3637 /*************************************************************************/
3638 /* */
3639 /* ROFF[]: Round OFF */
3640 /* Opcode range: 0x7A */
3641 /* Stack: --> */
3642 /* */
3643 static void
3644 Ins_ROFF( INS_ARG )
3645 {
3646 DO_ROFF
3647 }
3648
3649
3650 /*************************************************************************/
3651 /* */
3652 /* SROUND[]: Super ROUND */
3653 /* Opcode range: 0x76 */
3654 /* Stack: Eint8 --> */
3655 /* */
3656 static void
3657 Ins_SROUND( INS_ARG )
3658 {
3659 DO_SROUND
3660 }
3661
3662
3663 /*************************************************************************/
3664 /* */
3665 /* S45ROUND[]: Super ROUND 45 degrees */
3666 /* Opcode range: 0x77 */
3667 /* Stack: uint32 --> */
3668 /* */
3669 static void
3670 Ins_S45ROUND( INS_ARG )
3671 {
3672 DO_S45ROUND
3673 }
3674 3304
3675 3305
3676 /*************************************************************************/ 3306 /*************************************************************************/
3677 /* */ 3307 /* */
3678 /* SLOOP[]: Set LOOP variable */ 3308 /* SLOOP[]: Set LOOP variable */
3679 /* Opcode range: 0x17 */ 3309 /* Opcode range: 0x17 */
3680 /* Stack: int32? --> */ 3310 /* Stack: int32? --> */
3681 /* */ 3311 /* */
3682 static void 3312 static void
3683 Ins_SLOOP( INS_ARG ) 3313 Ins_SLOOP( TT_ExecContext exc,
3684 { 3314 FT_Long* args )
3685 DO_SLOOP 3315 {
3686 } 3316 if ( args[0] < 0 )
3687 3317 exc->error = FT_THROW( Bad_Argument );
3688
3689 /*************************************************************************/
3690 /* */
3691 /* SMD[]: Set Minimum Distance */
3692 /* Opcode range: 0x1A */
3693 /* Stack: f26.6 --> */
3694 /* */
3695 static void
3696 Ins_SMD( INS_ARG )
3697 {
3698 DO_SMD
3699 }
3700
3701
3702 /*************************************************************************/
3703 /* */
3704 /* SCVTCI[]: Set Control Value Table Cut In */
3705 /* Opcode range: 0x1D */
3706 /* Stack: f26.6 --> */
3707 /* */
3708 static void
3709 Ins_SCVTCI( INS_ARG )
3710 {
3711 DO_SCVTCI
3712 }
3713
3714
3715 /*************************************************************************/
3716 /* */
3717 /* SSWCI[]: Set Single Width Cut In */
3718 /* Opcode range: 0x1E */
3719 /* Stack: f26.6 --> */
3720 /* */
3721 static void
3722 Ins_SSWCI( INS_ARG )
3723 {
3724 DO_SSWCI
3725 }
3726
3727
3728 /*************************************************************************/
3729 /* */
3730 /* SSW[]: Set Single Width */
3731 /* Opcode range: 0x1F */
3732 /* Stack: int32? --> */
3733 /* */
3734 static void
3735 Ins_SSW( INS_ARG )
3736 {
3737 DO_SSW
3738 }
3739
3740
3741 /*************************************************************************/
3742 /* */
3743 /* FLIPON[]: Set auto-FLIP to ON */
3744 /* Opcode range: 0x4D */
3745 /* Stack: --> */
3746 /* */
3747 static void
3748 Ins_FLIPON( INS_ARG )
3749 {
3750 DO_FLIPON
3751 }
3752
3753
3754 /*************************************************************************/
3755 /* */
3756 /* FLIPOFF[]: Set auto-FLIP to OFF */
3757 /* Opcode range: 0x4E */
3758 /* Stack: --> */
3759 /* */
3760 static void
3761 Ins_FLIPOFF( INS_ARG )
3762 {
3763 DO_FLIPOFF
3764 }
3765
3766
3767 /*************************************************************************/
3768 /* */
3769 /* SANGW[]: Set ANGle Weight */
3770 /* Opcode range: 0x7E */
3771 /* Stack: uint32 --> */
3772 /* */
3773 static void
3774 Ins_SANGW( INS_ARG )
3775 {
3776 /* instruction not supported anymore */
3777 }
3778
3779
3780 /*************************************************************************/
3781 /* */
3782 /* SDB[]: Set Delta Base */
3783 /* Opcode range: 0x5E */
3784 /* Stack: uint32 --> */
3785 /* */
3786 static void
3787 Ins_SDB( INS_ARG )
3788 {
3789 DO_SDB
3790 }
3791
3792
3793 /*************************************************************************/
3794 /* */
3795 /* SDS[]: Set Delta Shift */
3796 /* Opcode range: 0x5F */
3797 /* Stack: uint32 --> */
3798 /* */
3799 static void
3800 Ins_SDS( INS_ARG )
3801 {
3802 DO_SDS
3803 }
3804
3805
3806 /*************************************************************************/
3807 /* */
3808 /* MPPEM[]: Measure Pixel Per EM */
3809 /* Opcode range: 0x4B */
3810 /* Stack: --> Euint16 */
3811 /* */
3812 static void
3813 Ins_MPPEM( INS_ARG )
3814 {
3815 DO_MPPEM
3816 }
3817
3818
3819 /*************************************************************************/
3820 /* */
3821 /* MPS[]: Measure Point Size */
3822 /* Opcode range: 0x4C */
3823 /* Stack: --> Euint16 */
3824 /* */
3825 static void
3826 Ins_MPS( INS_ARG )
3827 {
3828 DO_MPS
3829 }
3830
3831
3832 /*************************************************************************/
3833 /* */
3834 /* DUP[]: DUPlicate the top stack's element */
3835 /* Opcode range: 0x20 */
3836 /* Stack: StkElt --> StkElt StkElt */
3837 /* */
3838 static void
3839 Ins_DUP( INS_ARG )
3840 {
3841 DO_DUP
3842 }
3843
3844
3845 /*************************************************************************/
3846 /* */
3847 /* POP[]: POP the stack's top element */
3848 /* Opcode range: 0x21 */
3849 /* Stack: StkElt --> */
3850 /* */
3851 static void
3852 Ins_POP( INS_ARG )
3853 {
3854 /* nothing to do */
3855 }
3856
3857
3858 /*************************************************************************/
3859 /* */
3860 /* CLEAR[]: CLEAR the entire stack */
3861 /* Opcode range: 0x22 */
3862 /* Stack: StkElt... --> */
3863 /* */
3864 static void
3865 Ins_CLEAR( INS_ARG )
3866 {
3867 DO_CLEAR
3868 }
3869
3870
3871 /*************************************************************************/
3872 /* */
3873 /* SWAP[]: SWAP the stack's top two elements */
3874 /* Opcode range: 0x23 */
3875 /* Stack: 2 * StkElt --> 2 * StkElt */
3876 /* */
3877 static void
3878 Ins_SWAP( INS_ARG )
3879 {
3880 DO_SWAP
3881 }
3882
3883
3884 /*************************************************************************/
3885 /* */
3886 /* DEPTH[]: return the stack DEPTH */
3887 /* Opcode range: 0x24 */
3888 /* Stack: --> uint32 */
3889 /* */
3890 static void
3891 Ins_DEPTH( INS_ARG )
3892 {
3893 DO_DEPTH
3894 }
3895
3896
3897 /*************************************************************************/
3898 /* */
3899 /* CINDEX[]: Copy INDEXed element */
3900 /* Opcode range: 0x25 */
3901 /* Stack: int32 --> StkElt */
3902 /* */
3903 static void
3904 Ins_CINDEX( INS_ARG )
3905 {
3906 DO_CINDEX
3907 }
3908
3909
3910 /*************************************************************************/
3911 /* */
3912 /* EIF[]: End IF */
3913 /* Opcode range: 0x59 */
3914 /* Stack: --> */
3915 /* */
3916 static void
3917 Ins_EIF( INS_ARG )
3918 {
3919 /* nothing to do */
3920 }
3921
3922
3923 /*************************************************************************/
3924 /* */
3925 /* JROT[]: Jump Relative On True */
3926 /* Opcode range: 0x78 */
3927 /* Stack: StkElt int32 --> */
3928 /* */
3929 static void
3930 Ins_JROT( INS_ARG )
3931 {
3932 DO_JROT
3933 }
3934
3935
3936 /*************************************************************************/
3937 /* */
3938 /* JMPR[]: JuMP Relative */
3939 /* Opcode range: 0x1C */
3940 /* Stack: int32 --> */
3941 /* */
3942 static void
3943 Ins_JMPR( INS_ARG )
3944 {
3945 DO_JMPR
3946 }
3947
3948
3949 /*************************************************************************/
3950 /* */
3951 /* JROF[]: Jump Relative On False */
3952 /* Opcode range: 0x79 */
3953 /* Stack: StkElt int32 --> */
3954 /* */
3955 static void
3956 Ins_JROF( INS_ARG )
3957 {
3958 DO_JROF
3959 }
3960
3961
3962 /*************************************************************************/
3963 /* */
3964 /* LT[]: Less Than */
3965 /* Opcode range: 0x50 */
3966 /* Stack: int32? int32? --> bool */
3967 /* */
3968 static void
3969 Ins_LT( INS_ARG )
3970 {
3971 DO_LT
3972 }
3973
3974
3975 /*************************************************************************/
3976 /* */
3977 /* LTEQ[]: Less Than or EQual */
3978 /* Opcode range: 0x51 */
3979 /* Stack: int32? int32? --> bool */
3980 /* */
3981 static void
3982 Ins_LTEQ( INS_ARG )
3983 {
3984 DO_LTEQ
3985 }
3986
3987
3988 /*************************************************************************/
3989 /* */
3990 /* GT[]: Greater Than */
3991 /* Opcode range: 0x52 */
3992 /* Stack: int32? int32? --> bool */
3993 /* */
3994 static void
3995 Ins_GT( INS_ARG )
3996 {
3997 DO_GT
3998 }
3999
4000
4001 /*************************************************************************/
4002 /* */
4003 /* GTEQ[]: Greater Than or EQual */
4004 /* Opcode range: 0x53 */
4005 /* Stack: int32? int32? --> bool */
4006 /* */
4007 static void
4008 Ins_GTEQ( INS_ARG )
4009 {
4010 DO_GTEQ
4011 }
4012
4013
4014 /*************************************************************************/
4015 /* */
4016 /* EQ[]: EQual */
4017 /* Opcode range: 0x54 */
4018 /* Stack: StkElt StkElt --> bool */
4019 /* */
4020 static void
4021 Ins_EQ( INS_ARG )
4022 {
4023 DO_EQ
4024 }
4025
4026
4027 /*************************************************************************/
4028 /* */
4029 /* NEQ[]: Not EQual */
4030 /* Opcode range: 0x55 */
4031 /* Stack: StkElt StkElt --> bool */
4032 /* */
4033 static void
4034 Ins_NEQ( INS_ARG )
4035 {
4036 DO_NEQ
4037 }
4038
4039
4040 /*************************************************************************/
4041 /* */
4042 /* ODD[]: Is ODD */
4043 /* Opcode range: 0x56 */
4044 /* Stack: f26.6 --> bool */
4045 /* */
4046 static void
4047 Ins_ODD( INS_ARG )
4048 {
4049 DO_ODD
4050 }
4051
4052
4053 /*************************************************************************/
4054 /* */
4055 /* EVEN[]: Is EVEN */
4056 /* Opcode range: 0x57 */
4057 /* Stack: f26.6 --> bool */
4058 /* */
4059 static void
4060 Ins_EVEN( INS_ARG )
4061 {
4062 DO_EVEN
4063 }
4064
4065
4066 /*************************************************************************/
4067 /* */
4068 /* AND[]: logical AND */
4069 /* Opcode range: 0x5A */
4070 /* Stack: uint32 uint32 --> uint32 */
4071 /* */
4072 static void
4073 Ins_AND( INS_ARG )
4074 {
4075 DO_AND
4076 }
4077
4078
4079 /*************************************************************************/
4080 /* */
4081 /* OR[]: logical OR */
4082 /* Opcode range: 0x5B */
4083 /* Stack: uint32 uint32 --> uint32 */
4084 /* */
4085 static void
4086 Ins_OR( INS_ARG )
4087 {
4088 DO_OR
4089 }
4090
4091
4092 /*************************************************************************/
4093 /* */
4094 /* NOT[]: logical NOT */
4095 /* Opcode range: 0x5C */
4096 /* Stack: StkElt --> uint32 */
4097 /* */
4098 static void
4099 Ins_NOT( INS_ARG )
4100 {
4101 DO_NOT
4102 }
4103
4104
4105 /*************************************************************************/
4106 /* */
4107 /* ADD[]: ADD */
4108 /* Opcode range: 0x60 */
4109 /* Stack: f26.6 f26.6 --> f26.6 */
4110 /* */
4111 static void
4112 Ins_ADD( INS_ARG )
4113 {
4114 DO_ADD
4115 }
4116
4117
4118 /*************************************************************************/
4119 /* */
4120 /* SUB[]: SUBtract */
4121 /* Opcode range: 0x61 */
4122 /* Stack: f26.6 f26.6 --> f26.6 */
4123 /* */
4124 static void
4125 Ins_SUB( INS_ARG )
4126 {
4127 DO_SUB
4128 }
4129
4130
4131 /*************************************************************************/
4132 /* */
4133 /* DIV[]: DIVide */
4134 /* Opcode range: 0x62 */
4135 /* Stack: f26.6 f26.6 --> f26.6 */
4136 /* */
4137 static void
4138 Ins_DIV( INS_ARG )
4139 {
4140 DO_DIV
4141 }
4142
4143
4144 /*************************************************************************/
4145 /* */
4146 /* MUL[]: MULtiply */
4147 /* Opcode range: 0x63 */
4148 /* Stack: f26.6 f26.6 --> f26.6 */
4149 /* */
4150 static void
4151 Ins_MUL( INS_ARG )
4152 {
4153 DO_MUL
4154 }
4155
4156
4157 /*************************************************************************/
4158 /* */
4159 /* ABS[]: ABSolute value */
4160 /* Opcode range: 0x64 */
4161 /* Stack: f26.6 --> f26.6 */
4162 /* */
4163 static void
4164 Ins_ABS( INS_ARG )
4165 {
4166 DO_ABS
4167 }
4168
4169
4170 /*************************************************************************/
4171 /* */
4172 /* NEG[]: NEGate */
4173 /* Opcode range: 0x65 */
4174 /* Stack: f26.6 --> f26.6 */
4175 /* */
4176 static void
4177 Ins_NEG( INS_ARG )
4178 {
4179 DO_NEG
4180 }
4181
4182
4183 /*************************************************************************/
4184 /* */
4185 /* FLOOR[]: FLOOR */
4186 /* Opcode range: 0x66 */
4187 /* Stack: f26.6 --> f26.6 */
4188 /* */
4189 static void
4190 Ins_FLOOR( INS_ARG )
4191 {
4192 DO_FLOOR
4193 }
4194
4195
4196 /*************************************************************************/
4197 /* */
4198 /* CEILING[]: CEILING */
4199 /* Opcode range: 0x67 */
4200 /* Stack: f26.6 --> f26.6 */
4201 /* */
4202 static void
4203 Ins_CEILING( INS_ARG )
4204 {
4205 DO_CEILING
4206 }
4207
4208
4209 /*************************************************************************/
4210 /* */
4211 /* RS[]: Read Store */
4212 /* Opcode range: 0x43 */
4213 /* Stack: uint32 --> uint32 */
4214 /* */
4215 static void
4216 Ins_RS( INS_ARG )
4217 {
4218 DO_RS
4219 }
4220
4221
4222 /*************************************************************************/
4223 /* */
4224 /* WS[]: Write Store */
4225 /* Opcode range: 0x42 */
4226 /* Stack: uint32 uint32 --> */
4227 /* */
4228 static void
4229 Ins_WS( INS_ARG )
4230 {
4231 DO_WS
4232 }
4233
4234
4235 /*************************************************************************/
4236 /* */
4237 /* WCVTP[]: Write CVT in Pixel units */
4238 /* Opcode range: 0x44 */
4239 /* Stack: f26.6 uint32 --> */
4240 /* */
4241 static void
4242 Ins_WCVTP( INS_ARG )
4243 {
4244 DO_WCVTP
4245 }
4246
4247
4248 /*************************************************************************/
4249 /* */
4250 /* WCVTF[]: Write CVT in Funits */
4251 /* Opcode range: 0x70 */
4252 /* Stack: uint32 uint32 --> */
4253 /* */
4254 static void
4255 Ins_WCVTF( INS_ARG )
4256 {
4257 DO_WCVTF
4258 }
4259
4260
4261 /*************************************************************************/
4262 /* */
4263 /* RCVT[]: Read CVT */
4264 /* Opcode range: 0x45 */
4265 /* Stack: uint32 --> f26.6 */
4266 /* */
4267 static void
4268 Ins_RCVT( INS_ARG )
4269 {
4270 DO_RCVT
4271 }
4272
4273
4274 /*************************************************************************/
4275 /* */
4276 /* AA[]: Adjust Angle */
4277 /* Opcode range: 0x7F */
4278 /* Stack: uint32 --> */
4279 /* */
4280 static void
4281 Ins_AA( INS_ARG )
4282 {
4283 /* intentionally no longer supported */
4284 }
4285
4286
4287 /*************************************************************************/
4288 /* */
4289 /* DEBUG[]: DEBUG. Unsupported. */
4290 /* Opcode range: 0x4F */
4291 /* Stack: uint32 --> */
4292 /* */
4293 /* Note: The original instruction pops a value from the stack. */
4294 /* */
4295 static void
4296 Ins_DEBUG( INS_ARG )
4297 {
4298 DO_DEBUG
4299 }
4300
4301
4302 /*************************************************************************/
4303 /* */
4304 /* ROUND[ab]: ROUND value */
4305 /* Opcode range: 0x68-0x6B */
4306 /* Stack: f26.6 --> f26.6 */
4307 /* */
4308 static void
4309 Ins_ROUND( INS_ARG )
4310 {
4311 DO_ROUND
4312 }
4313
4314
4315 /*************************************************************************/
4316 /* */
4317 /* NROUND[ab]: No ROUNDing of value */
4318 /* Opcode range: 0x6C-0x6F */
4319 /* Stack: f26.6 --> f26.6 */
4320 /* */
4321 static void
4322 Ins_NROUND( INS_ARG )
4323 {
4324 DO_NROUND
4325 }
4326
4327
4328 /*************************************************************************/
4329 /* */
4330 /* MAX[]: MAXimum */
4331 /* Opcode range: 0x68 */
4332 /* Stack: int32? int32? --> int32 */
4333 /* */
4334 static void
4335 Ins_MAX( INS_ARG )
4336 {
4337 DO_MAX
4338 }
4339
4340
4341 /*************************************************************************/
4342 /* */
4343 /* MIN[]: MINimum */
4344 /* Opcode range: 0x69 */
4345 /* Stack: int32? int32? --> int32 */
4346 /* */
4347 static void
4348 Ins_MIN( INS_ARG )
4349 {
4350 DO_MIN
4351 }
4352
4353
4354 #endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
4355
4356
4357 /*************************************************************************/
4358 /* */
4359 /* The following functions are called as is within the switch statement. */
4360 /* */
4361 /*************************************************************************/
4362
4363
4364 /*************************************************************************/
4365 /* */
4366 /* MINDEX[]: Move INDEXed element */
4367 /* Opcode range: 0x26 */
4368 /* Stack: int32? --> StkElt */
4369 /* */
4370 static void
4371 Ins_MINDEX( INS_ARG )
4372 {
4373 FT_Long L, K;
4374
4375
4376 L = args[0];
4377
4378 if ( L <= 0 || L > CUR.args )
4379 {
4380 if ( CUR.pedantic_hinting )
4381 CUR.error = FT_THROW( Invalid_Reference );
4382 }
4383 else 3318 else
4384 { 3319 exc->GS.loop = args[0];
4385 K = CUR.stack[CUR.args - L]; 3320 }
4386
4387 FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ],
4388 &CUR.stack[CUR.args - L + 1],
4389 ( L - 1 ) );
4390
4391 CUR.stack[CUR.args - 1] = K;
4392 }
4393 }
4394
4395
4396 /*************************************************************************/
4397 /* */
4398 /* ROLL[]: ROLL top three elements */
4399 /* Opcode range: 0x8A */
4400 /* Stack: 3 * StkElt --> 3 * StkElt */
4401 /* */
4402 static void
4403 Ins_ROLL( INS_ARG )
4404 {
4405 FT_Long A, B, C;
4406
4407 FT_UNUSED_EXEC;
4408
4409
4410 A = args[2];
4411 B = args[1];
4412 C = args[0];
4413
4414 args[2] = C;
4415 args[1] = A;
4416 args[0] = B;
4417 }
4418
4419
4420 /*************************************************************************/
4421 /* */
4422 /* MANAGING THE FLOW OF CONTROL */
4423 /* */
4424 /* Instructions appear in the specification's order. */
4425 /* */
4426 /*************************************************************************/
4427 3321
4428 3322
4429 static FT_Bool 3323 static FT_Bool
4430 SkipCode( EXEC_OP ) 3324 SkipCode( TT_ExecContext exc )
4431 { 3325 {
4432 CUR.IP += CUR.length; 3326 exc->IP += exc->length;
4433 3327
4434 if ( CUR.IP < CUR.codeSize ) 3328 if ( exc->IP < exc->codeSize )
4435 { 3329 {
4436 CUR.opcode = CUR.code[CUR.IP]; 3330 exc->opcode = exc->code[exc->IP];
4437 3331
4438 CUR.length = opcode_length[CUR.opcode]; 3332 exc->length = opcode_length[exc->opcode];
4439 if ( CUR.length < 0 ) 3333 if ( exc->length < 0 )
4440 { 3334 {
4441 if ( CUR.IP + 1 >= CUR.codeSize ) 3335 if ( exc->IP + 1 >= exc->codeSize )
4442 goto Fail_Overflow; 3336 goto Fail_Overflow;
4443 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; 3337 exc->length = 2 - exc->length * exc->code[exc->IP + 1];
4444 } 3338 }
4445 3339
4446 if ( CUR.IP + CUR.length <= CUR.codeSize ) 3340 if ( exc->IP + exc->length <= exc->codeSize )
4447 return SUCCESS; 3341 return SUCCESS;
4448 } 3342 }
4449 3343
4450 Fail_Overflow: 3344 Fail_Overflow:
4451 CUR.error = FT_THROW( Code_Overflow ); 3345 exc->error = FT_THROW( Code_Overflow );
4452 return FAILURE; 3346 return FAILURE;
4453 } 3347 }
4454 3348
4455 3349
4456 /*************************************************************************/ 3350 /*************************************************************************/
4457 /* */ 3351 /* */
4458 /* IF[]: IF test */ 3352 /* IF[]: IF test */
4459 /* Opcode range: 0x58 */ 3353 /* Opcode range: 0x58 */
4460 /* Stack: StkElt --> */ 3354 /* Stack: StkElt --> */
4461 /* */ 3355 /* */
4462 static void 3356 static void
4463 Ins_IF( INS_ARG ) 3357 Ins_IF( TT_ExecContext exc,
3358 FT_Long* args )
4464 { 3359 {
4465 FT_Int nIfs; 3360 FT_Int nIfs;
4466 FT_Bool Out; 3361 FT_Bool Out;
4467 3362
4468 3363
4469 if ( args[0] != 0 ) 3364 if ( args[0] != 0 )
4470 return; 3365 return;
4471 3366
4472 nIfs = 1; 3367 nIfs = 1;
4473 Out = 0; 3368 Out = 0;
4474 3369
4475 do 3370 do
4476 { 3371 {
4477 if ( SKIP_Code() == FAILURE ) 3372 if ( SkipCode( exc ) == FAILURE )
4478 return; 3373 return;
4479 3374
4480 switch ( CUR.opcode ) 3375 switch ( exc->opcode )
4481 { 3376 {
4482 case 0x58: /* IF */ 3377 case 0x58: /* IF */
4483 nIfs++; 3378 nIfs++;
4484 break; 3379 break;
4485 3380
4486 case 0x1B: /* ELSE */ 3381 case 0x1B: /* ELSE */
4487 Out = FT_BOOL( nIfs == 1 ); 3382 Out = FT_BOOL( nIfs == 1 );
4488 break; 3383 break;
4489 3384
4490 case 0x59: /* EIF */ 3385 case 0x59: /* EIF */
4491 nIfs--; 3386 nIfs--;
4492 Out = FT_BOOL( nIfs == 0 ); 3387 Out = FT_BOOL( nIfs == 0 );
4493 break; 3388 break;
4494 } 3389 }
4495 } while ( Out == 0 ); 3390 } while ( Out == 0 );
4496 } 3391 }
4497 3392
4498 3393
4499 /*************************************************************************/ 3394 /*************************************************************************/
4500 /* */ 3395 /* */
4501 /* ELSE[]: ELSE */ 3396 /* ELSE[]: ELSE */
4502 /* Opcode range: 0x1B */ 3397 /* Opcode range: 0x1B */
4503 /* Stack: --> */ 3398 /* Stack: --> */
4504 /* */ 3399 /* */
4505 static void 3400 static void
4506 Ins_ELSE( INS_ARG ) 3401 Ins_ELSE( TT_ExecContext exc )
4507 { 3402 {
4508 FT_Int nIfs; 3403 FT_Int nIfs;
4509 3404
4510 FT_UNUSED_ARG;
4511
4512 3405
4513 nIfs = 1; 3406 nIfs = 1;
4514 3407
4515 do 3408 do
4516 { 3409 {
4517 if ( SKIP_Code() == FAILURE ) 3410 if ( SkipCode( exc ) == FAILURE )
4518 return; 3411 return;
4519 3412
4520 switch ( CUR.opcode ) 3413 switch ( exc->opcode )
4521 { 3414 {
4522 case 0x58: /* IF */ 3415 case 0x58: /* IF */
4523 nIfs++; 3416 nIfs++;
4524 break; 3417 break;
4525 3418
4526 case 0x59: /* EIF */ 3419 case 0x59: /* EIF */
4527 nIfs--; 3420 nIfs--;
4528 break; 3421 break;
4529 } 3422 }
4530 } while ( nIfs != 0 ); 3423 } while ( nIfs != 0 );
4531 } 3424 }
4532 3425
4533 3426
4534 /*************************************************************************/ 3427 /*************************************************************************/
4535 /* */ 3428 /* */
3429 /* EIF[]: End IF */
3430 /* Opcode range: 0x59 */
3431 /* Stack: --> */
3432 /* */
3433 static void
3434 Ins_EIF( void )
3435 {
3436 /* nothing to do */
3437 }
3438
3439
3440 /*************************************************************************/
3441 /* */
3442 /* JMPR[]: JuMP Relative */
3443 /* Opcode range: 0x1C */
3444 /* Stack: int32 --> */
3445 /* */
3446 static void
3447 Ins_JMPR( TT_ExecContext exc,
3448 FT_Long* args )
3449 {
3450 if ( args[0] == 0 && exc->args == 0 )
3451 exc->error = FT_THROW( Bad_Argument );
3452 exc->IP += args[0];
3453 if ( exc->IP < 0 ||
3454 ( exc->callTop > 0 &&
3455 exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
3456 exc->error = FT_THROW( Bad_Argument );
3457 exc->step_ins = FALSE;
3458 }
3459
3460
3461 /*************************************************************************/
3462 /* */
3463 /* JROT[]: Jump Relative On True */
3464 /* Opcode range: 0x78 */
3465 /* Stack: StkElt int32 --> */
3466 /* */
3467 static void
3468 Ins_JROT( TT_ExecContext exc,
3469 FT_Long* args )
3470 {
3471 if ( args[1] != 0 )
3472 Ins_JMPR( exc, args );
3473 }
3474
3475
3476 /*************************************************************************/
3477 /* */
3478 /* JROF[]: Jump Relative On False */
3479 /* Opcode range: 0x79 */
3480 /* Stack: StkElt int32 --> */
3481 /* */
3482 static void
3483 Ins_JROF( TT_ExecContext exc,
3484 FT_Long* args )
3485 {
3486 if ( args[1] == 0 )
3487 Ins_JMPR( exc, args );
3488 }
3489
3490
3491 /*************************************************************************/
3492 /* */
4536 /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ 3493 /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
4537 /* */ 3494 /* */
4538 /* Instructions appear in the specification's order. */
4539 /* */
4540 /*************************************************************************/ 3495 /*************************************************************************/
4541 3496
4542 3497
4543 /*************************************************************************/ 3498 /*************************************************************************/
4544 /* */ 3499 /* */
4545 /* FDEF[]: Function DEFinition */ 3500 /* FDEF[]: Function DEFinition */
4546 /* Opcode range: 0x2C */ 3501 /* Opcode range: 0x2C */
4547 /* Stack: uint32 --> */ 3502 /* Stack: uint32 --> */
4548 /* */ 3503 /* */
4549 static void 3504 static void
4550 Ins_FDEF( INS_ARG ) 3505 Ins_FDEF( TT_ExecContext exc,
3506 FT_Long* args )
4551 { 3507 {
4552 FT_ULong n; 3508 FT_ULong n;
4553 TT_DefRecord* rec; 3509 TT_DefRecord* rec;
4554 TT_DefRecord* limit; 3510 TT_DefRecord* limit;
4555 3511
4556 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3512 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
4557 /* arguments to opcodes are skipped by `SKIP_Code' */ 3513 /* arguments to opcodes are skipped by `SKIP_Code' */
4558 FT_Byte opcode_pattern[9][12] = { 3514 FT_Byte opcode_pattern[9][12] = {
4559 /* #0 inline delta function 1 */ 3515 /* #0 inline delta function 1 */
4560 { 3516 {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
4650 FT_UShort opcode_patterns = 9; 3606 FT_UShort opcode_patterns = 9;
4651 FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 3607 FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
4652 FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; 3608 FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
4653 FT_UShort i; 3609 FT_UShort i;
4654 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3610 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4655 3611
4656 3612
4657 /* some font programs are broken enough to redefine functions! */ 3613 /* some font programs are broken enough to redefine functions! */
4658 /* We will then parse the current table. */ 3614 /* We will then parse the current table. */
4659 3615
4660 rec = CUR.FDefs; 3616 rec = exc->FDefs;
4661 limit = rec + CUR.numFDefs; 3617 limit = rec + exc->numFDefs;
4662 n = args[0]; 3618 n = (FT_ULong)args[0];
4663 3619
4664 for ( ; rec < limit; rec++ ) 3620 for ( ; rec < limit; rec++ )
4665 { 3621 {
4666 if ( rec->opc == n ) 3622 if ( rec->opc == n )
4667 break; 3623 break;
4668 } 3624 }
4669 3625
4670 if ( rec == limit ) 3626 if ( rec == limit )
4671 { 3627 {
4672 /* check that there is enough room for new functions */ 3628 /* check that there is enough room for new functions */
4673 if ( CUR.numFDefs >= CUR.maxFDefs ) 3629 if ( exc->numFDefs >= exc->maxFDefs )
4674 { 3630 {
4675 CUR.error = FT_THROW( Too_Many_Function_Defs ); 3631 exc->error = FT_THROW( Too_Many_Function_Defs );
4676 return; 3632 return;
4677 } 3633 }
4678 CUR.numFDefs++; 3634 exc->numFDefs++;
4679 } 3635 }
4680 3636
4681 /* Although FDEF takes unsigned 32-bit integer, */ 3637 /* Although FDEF takes unsigned 32-bit integer, */
4682 /* func # must be within unsigned 16-bit integer */ 3638 /* func # must be within unsigned 16-bit integer */
4683 if ( n > 0xFFFFU ) 3639 if ( n > 0xFFFFU )
4684 { 3640 {
4685 CUR.error = FT_THROW( Too_Many_Function_Defs ); 3641 exc->error = FT_THROW( Too_Many_Function_Defs );
4686 return; 3642 return;
4687 } 3643 }
4688 3644
4689 rec->range = CUR.curRange; 3645 rec->range = exc->curRange;
4690 rec->opc = (FT_UInt16)n; 3646 rec->opc = (FT_UInt16)n;
4691 rec->start = CUR.IP + 1; 3647 rec->start = exc->IP + 1;
4692 rec->active = TRUE; 3648 rec->active = TRUE;
4693 rec->inline_delta = FALSE; 3649 rec->inline_delta = FALSE;
4694 rec->sph_fdef_flags = 0x0000; 3650 rec->sph_fdef_flags = 0x0000;
4695 3651
4696 if ( n > CUR.maxFunc ) 3652 if ( n > exc->maxFunc )
4697 CUR.maxFunc = (FT_UInt16)n; 3653 exc->maxFunc = (FT_UInt16)n;
4698 3654
4699 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3655 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
4700 /* We don't know for sure these are typeman functions, */ 3656 /* We don't know for sure these are typeman functions, */
4701 /* however they are only active when RS 22 is called */ 3657 /* however they are only active when RS 22 is called */
4702 if ( n >= 64 && n <= 66 ) 3658 if ( n >= 64 && n <= 66 )
4703 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; 3659 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
4704 #endif 3660 #endif
4705 3661
4706 /* Now skip the whole function definition. */ 3662 /* Now skip the whole function definition. */
4707 /* We don't allow nested IDEFS & FDEFs. */ 3663 /* We don't allow nested IDEFS & FDEFs. */
4708 3664
4709 while ( SKIP_Code() == SUCCESS ) 3665 while ( SkipCode( exc ) == SUCCESS )
4710 { 3666 {
4711 3667
4712 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3668 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
4713 3669
4714 if ( SUBPIXEL_HINTING ) 3670 if ( SUBPIXEL_HINTING )
4715 { 3671 {
4716 for ( i = 0; i < opcode_patterns; i++ ) 3672 for ( i = 0; i < opcode_patterns; i++ )
4717 { 3673 {
4718 if ( opcode_pointer[i] < opcode_size[i] && 3674 if ( opcode_pointer[i] < opcode_size[i] &&
4719 CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) 3675 exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
4720 { 3676 {
4721 opcode_pointer[i] += 1; 3677 opcode_pointer[i] += 1;
4722 3678
4723 if ( opcode_pointer[i] == opcode_size[i] ) 3679 if ( opcode_pointer[i] == opcode_size[i] )
4724 { 3680 {
4725 FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", 3681 FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
4726 i, n, 3682 i, n,
4727 CUR.face->root.family_name, 3683 exc->face->root.family_name,
4728 CUR.face->root.style_name )); 3684 exc->face->root.style_name ));
4729 3685
4730 switch ( i ) 3686 switch ( i )
4731 { 3687 {
4732 case 0: 3688 case 0:
4733 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; 3689 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
4734 CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; 3690 exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
4735 break; 3691 break;
4736 3692
4737 case 1: 3693 case 1:
4738 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; 3694 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
4739 CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; 3695 exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
4740 break; 3696 break;
4741 3697
4742 case 2: 3698 case 2:
4743 switch ( n ) 3699 switch ( n )
4744 { 3700 {
4745 /* needs to be implemented still */ 3701 /* needs to be implemented still */
4746 case 58: 3702 case 58:
4747 rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; 3703 rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
4748 CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; 3704 exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
4749 } 3705 }
4750 break; 3706 break;
4751 3707
4752 case 3: 3708 case 3:
4753 switch ( n ) 3709 switch ( n )
4754 { 3710 {
4755 case 0: 3711 case 0:
4756 rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; 3712 rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
4757 CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; 3713 exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
4758 } 3714 }
4759 break; 3715 break;
4760 3716
4761 case 4: 3717 case 4:
4762 /* probably not necessary to detect anymore */ 3718 /* probably not necessary to detect anymore */
4763 rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; 3719 rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
4764 CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; 3720 exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
4765 break; 3721 break;
4766 3722
4767 case 5: 3723 case 5:
4768 switch ( n ) 3724 switch ( n )
4769 { 3725 {
4770 case 0: 3726 case 0:
4771 case 1: 3727 case 1:
4772 case 2: 3728 case 2:
4773 case 4: 3729 case 4:
4774 case 7: 3730 case 7:
4775 case 8: 3731 case 8:
4776 rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; 3732 rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
4777 CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; 3733 exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
4778 } 3734 }
4779 break; 3735 break;
4780 3736
4781 case 6: 3737 case 6:
4782 switch ( n ) 3738 switch ( n )
4783 { 3739 {
4784 case 0: 3740 case 0:
4785 case 1: 3741 case 1:
4786 case 2: 3742 case 2:
4787 case 4: 3743 case 4:
4788 case 7: 3744 case 7:
4789 case 8: 3745 case 8:
4790 rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; 3746 rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
4791 CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; 3747 exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
4792 } 3748 }
4793 break; 3749 break;
4794 3750
4795 case 7: 3751 case 7:
4796 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; 3752 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL ;
4797 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; 3753 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL ;
4798 break; 3754 break;
4799 3755
4800 case 8: 3756 case 8:
4801 #if 0 3757 #if 0
4802 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; 3758 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL ;
4803 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; 3759 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL ;
4804 #endif 3760 #endif
4805 break; 3761 break;
4806 } 3762 }
4807 opcode_pointer[i] = 0; 3763 opcode_pointer[i] = 0;
4808 } 3764 }
4809 } 3765 }
4810 3766
4811 else 3767 else
4812 opcode_pointer[i] = 0; 3768 opcode_pointer[i] = 0;
4813 } 3769 }
4814 3770
4815 /* Set sph_compatibility_mode only when deltas are detected */ 3771 /* Set sph_compatibility_mode only when deltas are detected */
4816 CUR.face->sph_compatibility_mode = 3772 exc->face->sph_compatibility_mode =
4817 ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | 3773 ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
4818 ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); 3774 ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
4819 } 3775 }
4820 3776
4821 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3777 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4822 3778
4823 switch ( CUR.opcode ) 3779 switch ( exc->opcode )
4824 { 3780 {
4825 case 0x89: /* IDEF */ 3781 case 0x89: /* IDEF */
4826 case 0x2C: /* FDEF */ 3782 case 0x2C: /* FDEF */
4827 CUR.error = FT_THROW( Nested_DEFS ); 3783 exc->error = FT_THROW( Nested_DEFS );
4828 return; 3784 return;
4829 3785
4830 case 0x2D: /* ENDF */ 3786 case 0x2D: /* ENDF */
4831 rec->end = CUR.IP; 3787 rec->end = exc->IP;
4832 return; 3788 return;
4833 } 3789 }
4834 } 3790 }
4835 } 3791 }
4836 3792
4837 3793
4838 /*************************************************************************/ 3794 /*************************************************************************/
4839 /* */ 3795 /* */
4840 /* ENDF[]: END Function definition */ 3796 /* ENDF[]: END Function definition */
4841 /* Opcode range: 0x2D */ 3797 /* Opcode range: 0x2D */
4842 /* Stack: --> */ 3798 /* Stack: --> */
4843 /* */ 3799 /* */
4844 static void 3800 static void
4845 Ins_ENDF( INS_ARG ) 3801 Ins_ENDF( TT_ExecContext exc )
4846 { 3802 {
4847 TT_CallRec* pRec; 3803 TT_CallRec* pRec;
4848 3804
4849 FT_UNUSED_ARG;
4850
4851 3805
4852 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3806 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
4853 CUR.sph_in_func_flags = 0x0000; 3807 exc->sph_in_func_flags = 0x0000;
4854 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3808 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4855 3809
4856 if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ 3810 if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */
4857 { 3811 {
4858 CUR.error = FT_THROW( ENDF_In_Exec_Stream ); 3812 exc->error = FT_THROW( ENDF_In_Exec_Stream );
4859 return; 3813 return;
4860 } 3814 }
4861 3815
4862 CUR.callTop--; 3816 exc->callTop--;
4863 3817
4864 pRec = &CUR.callStack[CUR.callTop]; 3818 pRec = &exc->callStack[exc->callTop];
4865 3819
4866 pRec->Cur_Count--; 3820 pRec->Cur_Count--;
4867 3821
4868 CUR.step_ins = FALSE; 3822 exc->step_ins = FALSE;
4869 3823
4870 if ( pRec->Cur_Count > 0 ) 3824 if ( pRec->Cur_Count > 0 )
4871 { 3825 {
4872 CUR.callTop++; 3826 exc->callTop++;
4873 CUR.IP = pRec->Def->start; 3827 exc->IP = pRec->Def->start;
4874 } 3828 }
4875 else 3829 else
4876 /* Loop through the current function */ 3830 /* Loop through the current function */
4877 INS_Goto_CodeRange( pRec->Caller_Range, 3831 Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP );
4878 pRec->Caller_IP );
4879 3832
4880 /* Exit the current call frame. */ 3833 /* Exit the current call frame. */
4881 3834
4882 /* NOTE: If the last instruction of a program is a */ 3835 /* NOTE: If the last instruction of a program is a */
4883 /* CALL or LOOPCALL, the return address is */ 3836 /* CALL or LOOPCALL, the return address is */
4884 /* always out of the code range. This is a */ 3837 /* always out of the code range. This is a */
4885 /* valid address, and it is why we do not test */ 3838 /* valid address, and it is why we do not test */
4886 /* the result of Ins_Goto_CodeRange() here! */ 3839 /* the result of Ins_Goto_CodeRange() here! */
4887 } 3840 }
4888 3841
4889 3842
4890 /*************************************************************************/ 3843 /*************************************************************************/
4891 /* */ 3844 /* */
4892 /* CALL[]: CALL function */ 3845 /* CALL[]: CALL function */
4893 /* Opcode range: 0x2B */ 3846 /* Opcode range: 0x2B */
4894 /* Stack: uint32? --> */ 3847 /* Stack: uint32? --> */
4895 /* */ 3848 /* */
4896 static void 3849 static void
4897 Ins_CALL( INS_ARG ) 3850 Ins_CALL( TT_ExecContext exc,
3851 FT_Long* args )
4898 { 3852 {
4899 FT_ULong F; 3853 FT_ULong F;
4900 TT_CallRec* pCrec; 3854 TT_CallRec* pCrec;
4901 TT_DefRecord* def; 3855 TT_DefRecord* def;
4902 3856
4903 3857
4904 /* first of all, check the index */ 3858 /* first of all, check the index */
4905 3859
4906 F = args[0]; 3860 F = (FT_ULong)args[0];
4907 if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) 3861 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
4908 goto Fail; 3862 goto Fail;
4909 3863
4910 /* Except for some old Apple fonts, all functions in a TrueType */ 3864 /* Except for some old Apple fonts, all functions in a TrueType */
4911 /* font are defined in increasing order, starting from 0. This */ 3865 /* font are defined in increasing order, starting from 0. This */
4912 /* means that we normally have */ 3866 /* means that we normally have */
4913 /* */ 3867 /* */
4914 /* CUR.maxFunc+1 == CUR.numFDefs */ 3868 /* exc->maxFunc+1 == exc->numFDefs */
4915 /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ 3869 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
4916 /* */ 3870 /* */
4917 /* If this isn't true, we need to look up the function table. */ 3871 /* If this isn't true, we need to look up the function table. */
4918 3872
4919 def = CUR.FDefs + F; 3873 def = exc->FDefs + F;
4920 if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) 3874 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
4921 { 3875 {
4922 /* look up the FDefs table */ 3876 /* look up the FDefs table */
4923 TT_DefRecord* limit; 3877 TT_DefRecord* limit;
4924 3878
4925 3879
4926 def = CUR.FDefs; 3880 def = exc->FDefs;
4927 limit = def + CUR.numFDefs; 3881 limit = def + exc->numFDefs;
4928 3882
4929 while ( def < limit && def->opc != F ) 3883 while ( def < limit && def->opc != F )
4930 def++; 3884 def++;
4931 3885
4932 if ( def == limit ) 3886 if ( def == limit )
4933 goto Fail; 3887 goto Fail;
4934 } 3888 }
4935 3889
4936 /* check that the function is active */ 3890 /* check that the function is active */
4937 if ( !def->active ) 3891 if ( !def->active )
4938 goto Fail; 3892 goto Fail;
4939 3893
4940 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3894 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
4941 if ( SUBPIXEL_HINTING && 3895 if ( SUBPIXEL_HINTING &&
4942 CUR.ignore_x_mode && 3896 exc->ignore_x_mode &&
4943 ( ( CUR.iup_called && 3897 ( ( exc->iup_called &&
4944 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || 3898 ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
4945 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) 3899 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
4946 goto Fail; 3900 goto Fail;
4947 else 3901 else
4948 CUR.sph_in_func_flags = def->sph_fdef_flags; 3902 exc->sph_in_func_flags = def->sph_fdef_flags;
4949 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3903 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4950 3904
4951 /* check the call stack */ 3905 /* check the call stack */
4952 if ( CUR.callTop >= CUR.callSize ) 3906 if ( exc->callTop >= exc->callSize )
4953 { 3907 {
4954 CUR.error = FT_THROW( Stack_Overflow ); 3908 exc->error = FT_THROW( Stack_Overflow );
4955 return; 3909 return;
4956 } 3910 }
4957 3911
4958 pCrec = CUR.callStack + CUR.callTop; 3912 pCrec = exc->callStack + exc->callTop;
4959 3913
4960 pCrec->Caller_Range = CUR.curRange; 3914 pCrec->Caller_Range = exc->curRange;
4961 pCrec->Caller_IP = CUR.IP + 1; 3915 pCrec->Caller_IP = exc->IP + 1;
4962 pCrec->Cur_Count = 1; 3916 pCrec->Cur_Count = 1;
4963 pCrec->Def = def; 3917 pCrec->Def = def;
4964 3918
4965 CUR.callTop++; 3919 exc->callTop++;
4966 3920
4967 INS_Goto_CodeRange( def->range, 3921 Ins_Goto_CodeRange( exc, def->range, def->start );
4968 def->start ); 3922
4969 3923 exc->step_ins = FALSE;
4970 CUR.step_ins = FALSE;
4971 3924
4972 return; 3925 return;
4973 3926
4974 Fail: 3927 Fail:
4975 CUR.error = FT_THROW( Invalid_Reference ); 3928 exc->error = FT_THROW( Invalid_Reference );
4976 } 3929 }
4977 3930
4978 3931
4979 /*************************************************************************/ 3932 /*************************************************************************/
4980 /* */ 3933 /* */
4981 /* LOOPCALL[]: LOOP and CALL function */ 3934 /* LOOPCALL[]: LOOP and CALL function */
4982 /* Opcode range: 0x2A */ 3935 /* Opcode range: 0x2A */
4983 /* Stack: uint32? Eint16? --> */ 3936 /* Stack: uint32? Eint16? --> */
4984 /* */ 3937 /* */
4985 static void 3938 static void
4986 Ins_LOOPCALL( INS_ARG ) 3939 Ins_LOOPCALL( TT_ExecContext exc,
3940 FT_Long* args )
4987 { 3941 {
4988 FT_ULong F; 3942 FT_ULong F;
4989 TT_CallRec* pCrec; 3943 TT_CallRec* pCrec;
4990 TT_DefRecord* def; 3944 TT_DefRecord* def;
4991 3945
4992 3946
4993 /* first of all, check the index */ 3947 /* first of all, check the index */
4994 F = args[1]; 3948 F = (FT_ULong)args[1];
4995 if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) 3949 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
4996 goto Fail; 3950 goto Fail;
4997 3951
4998 /* Except for some old Apple fonts, all functions in a TrueType */ 3952 /* Except for some old Apple fonts, all functions in a TrueType */
4999 /* font are defined in increasing order, starting from 0. This */ 3953 /* font are defined in increasing order, starting from 0. This */
5000 /* means that we normally have */ 3954 /* means that we normally have */
5001 /* */ 3955 /* */
5002 /* CUR.maxFunc+1 == CUR.numFDefs */ 3956 /* exc->maxFunc+1 == exc->numFDefs */
5003 /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ 3957 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
5004 /* */ 3958 /* */
5005 /* If this isn't true, we need to look up the function table. */ 3959 /* If this isn't true, we need to look up the function table. */
5006 3960
5007 def = CUR.FDefs + F; 3961 def = exc->FDefs + F;
5008 if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) 3962 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
5009 { 3963 {
5010 /* look up the FDefs table */ 3964 /* look up the FDefs table */
5011 TT_DefRecord* limit; 3965 TT_DefRecord* limit;
5012 3966
5013 3967
5014 def = CUR.FDefs; 3968 def = exc->FDefs;
5015 limit = def + CUR.numFDefs; 3969 limit = def + exc->numFDefs;
5016 3970
5017 while ( def < limit && def->opc != F ) 3971 while ( def < limit && def->opc != F )
5018 def++; 3972 def++;
5019 3973
5020 if ( def == limit ) 3974 if ( def == limit )
5021 goto Fail; 3975 goto Fail;
5022 } 3976 }
5023 3977
5024 /* check that the function is active */ 3978 /* check that the function is active */
5025 if ( !def->active ) 3979 if ( !def->active )
5026 goto Fail; 3980 goto Fail;
5027 3981
5028 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 3982 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
5029 if ( SUBPIXEL_HINTING && 3983 if ( SUBPIXEL_HINTING &&
5030 CUR.ignore_x_mode && 3984 exc->ignore_x_mode &&
5031 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) 3985 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
5032 goto Fail; 3986 goto Fail;
5033 else 3987 else
5034 CUR.sph_in_func_flags = def->sph_fdef_flags; 3988 exc->sph_in_func_flags = def->sph_fdef_flags;
5035 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 3989 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
5036 3990
5037 /* check stack */ 3991 /* check stack */
5038 if ( CUR.callTop >= CUR.callSize ) 3992 if ( exc->callTop >= exc->callSize )
5039 { 3993 {
5040 CUR.error = FT_THROW( Stack_Overflow ); 3994 exc->error = FT_THROW( Stack_Overflow );
5041 return; 3995 return;
5042 } 3996 }
5043 3997
5044 if ( args[0] > 0 ) 3998 if ( args[0] > 0 )
5045 { 3999 {
5046 pCrec = CUR.callStack + CUR.callTop; 4000 pCrec = exc->callStack + exc->callTop;
5047 4001
5048 pCrec->Caller_Range = CUR.curRange; 4002 pCrec->Caller_Range = exc->curRange;
5049 pCrec->Caller_IP = CUR.IP + 1; 4003 pCrec->Caller_IP = exc->IP + 1;
5050 pCrec->Cur_Count = (FT_Int)args[0]; 4004 pCrec->Cur_Count = (FT_Int)args[0];
5051 pCrec->Def = def; 4005 pCrec->Def = def;
5052 4006
5053 CUR.callTop++; 4007 exc->callTop++;
5054 4008
5055 INS_Goto_CodeRange( def->range, def->start ); 4009 Ins_Goto_CodeRange( exc, def->range, def->start );
5056 4010
5057 CUR.step_ins = FALSE; 4011 exc->step_ins = FALSE;
5058 } 4012 }
5059 4013
5060 return; 4014 return;
5061 4015
5062 Fail: 4016 Fail:
5063 CUR.error = FT_THROW( Invalid_Reference ); 4017 exc->error = FT_THROW( Invalid_Reference );
5064 } 4018 }
5065 4019
5066 4020
5067 /*************************************************************************/ 4021 /*************************************************************************/
5068 /* */ 4022 /* */
5069 /* IDEF[]: Instruction DEFinition */ 4023 /* IDEF[]: Instruction DEFinition */
5070 /* Opcode range: 0x89 */ 4024 /* Opcode range: 0x89 */
5071 /* Stack: Eint8 --> */ 4025 /* Stack: Eint8 --> */
5072 /* */ 4026 /* */
5073 static void 4027 static void
5074 Ins_IDEF( INS_ARG ) 4028 Ins_IDEF( TT_ExecContext exc,
4029 FT_Long* args )
5075 { 4030 {
5076 TT_DefRecord* def; 4031 TT_DefRecord* def;
5077 TT_DefRecord* limit; 4032 TT_DefRecord* limit;
5078 4033
5079 4034
5080 /* First of all, look for the same function in our table */ 4035 /* First of all, look for the same function in our table */
5081 4036
5082 def = CUR.IDefs; 4037 def = exc->IDefs;
5083 limit = def + CUR.numIDefs; 4038 limit = def + exc->numIDefs;
5084 4039
5085 for ( ; def < limit; def++ ) 4040 for ( ; def < limit; def++ )
5086 if ( def->opc == (FT_ULong)args[0] ) 4041 if ( def->opc == (FT_ULong)args[0] )
5087 break; 4042 break;
5088 4043
5089 if ( def == limit ) 4044 if ( def == limit )
5090 { 4045 {
5091 /* check that there is enough room for a new instruction */ 4046 /* check that there is enough room for a new instruction */
5092 if ( CUR.numIDefs >= CUR.maxIDefs ) 4047 if ( exc->numIDefs >= exc->maxIDefs )
5093 { 4048 {
5094 CUR.error = FT_THROW( Too_Many_Instruction_Defs ); 4049 exc->error = FT_THROW( Too_Many_Instruction_Defs );
5095 return; 4050 return;
5096 } 4051 }
5097 CUR.numIDefs++; 4052 exc->numIDefs++;
5098 } 4053 }
5099 4054
5100 /* opcode must be unsigned 8-bit integer */ 4055 /* opcode must be unsigned 8-bit integer */
5101 if ( 0 > args[0] || args[0] > 0x00FF ) 4056 if ( 0 > args[0] || args[0] > 0x00FF )
5102 { 4057 {
5103 CUR.error = FT_THROW( Too_Many_Instruction_Defs ); 4058 exc->error = FT_THROW( Too_Many_Instruction_Defs );
5104 return; 4059 return;
5105 } 4060 }
5106 4061
5107 def->opc = (FT_Byte)args[0]; 4062 def->opc = (FT_Byte)args[0];
5108 def->start = CUR.IP + 1; 4063 def->start = exc->IP + 1;
5109 def->range = CUR.curRange; 4064 def->range = exc->curRange;
5110 def->active = TRUE; 4065 def->active = TRUE;
5111 4066
5112 if ( (FT_ULong)args[0] > CUR.maxIns ) 4067 if ( (FT_ULong)args[0] > exc->maxIns )
5113 CUR.maxIns = (FT_Byte)args[0]; 4068 exc->maxIns = (FT_Byte)args[0];
5114 4069
5115 /* Now skip the whole function definition. */ 4070 /* Now skip the whole function definition. */
5116 /* We don't allow nested IDEFs & FDEFs. */ 4071 /* We don't allow nested IDEFs & FDEFs. */
5117 4072
5118 while ( SKIP_Code() == SUCCESS ) 4073 while ( SkipCode( exc ) == SUCCESS )
5119 { 4074 {
5120 switch ( CUR.opcode ) 4075 switch ( exc->opcode )
5121 { 4076 {
5122 case 0x89: /* IDEF */ 4077 case 0x89: /* IDEF */
5123 case 0x2C: /* FDEF */ 4078 case 0x2C: /* FDEF */
5124 CUR.error = FT_THROW( Nested_DEFS ); 4079 exc->error = FT_THROW( Nested_DEFS );
5125 return; 4080 return;
5126 case 0x2D: /* ENDF */ 4081 case 0x2D: /* ENDF */
5127 return; 4082 return;
5128 } 4083 }
5129 } 4084 }
5130 } 4085 }
5131 4086
5132 4087
5133 /*************************************************************************/ 4088 /*************************************************************************/
5134 /* */ 4089 /* */
5135 /* PUSHING DATA ONTO THE INTERPRETER STACK */ 4090 /* PUSHING DATA ONTO THE INTERPRETER STACK */
5136 /* */ 4091 /* */
5137 /* Instructions appear in the specification's order. */
5138 /* */
5139 /*************************************************************************/ 4092 /*************************************************************************/
5140 4093
5141 4094
5142 /*************************************************************************/ 4095 /*************************************************************************/
5143 /* */ 4096 /* */
5144 /* NPUSHB[]: PUSH N Bytes */ 4097 /* NPUSHB[]: PUSH N Bytes */
5145 /* Opcode range: 0x40 */ 4098 /* Opcode range: 0x40 */
5146 /* Stack: --> uint32... */ 4099 /* Stack: --> uint32... */
5147 /* */ 4100 /* */
5148 static void 4101 static void
5149 Ins_NPUSHB( INS_ARG ) 4102 Ins_NPUSHB( TT_ExecContext exc,
4103 FT_Long* args )
5150 { 4104 {
5151 FT_UShort L, K; 4105 FT_UShort L, K;
5152 4106
5153 4107
5154 L = (FT_UShort)CUR.code[CUR.IP + 1]; 4108 L = (FT_UShort)exc->code[exc->IP + 1];
5155 4109
5156 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4110 if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
5157 { 4111 {
5158 CUR.error = FT_THROW( Stack_Overflow ); 4112 exc->error = FT_THROW( Stack_Overflow );
5159 return; 4113 return;
5160 } 4114 }
5161 4115
5162 for ( K = 1; K <= L; K++ ) 4116 for ( K = 1; K <= L; K++ )
5163 args[K - 1] = CUR.code[CUR.IP + K + 1]; 4117 args[K - 1] = exc->code[exc->IP + K + 1];
5164 4118
5165 CUR.new_top += L; 4119 exc->new_top += L;
5166 } 4120 }
5167 4121
5168 4122
5169 /*************************************************************************/ 4123 /*************************************************************************/
5170 /* */ 4124 /* */
5171 /* NPUSHW[]: PUSH N Words */ 4125 /* NPUSHW[]: PUSH N Words */
5172 /* Opcode range: 0x41 */ 4126 /* Opcode range: 0x41 */
5173 /* Stack: --> int32... */ 4127 /* Stack: --> int32... */
5174 /* */ 4128 /* */
5175 static void 4129 static void
5176 Ins_NPUSHW( INS_ARG ) 4130 Ins_NPUSHW( TT_ExecContext exc,
4131 FT_Long* args )
5177 { 4132 {
5178 FT_UShort L, K; 4133 FT_UShort L, K;
5179 4134
5180 4135
5181 L = (FT_UShort)CUR.code[CUR.IP + 1]; 4136 L = (FT_UShort)exc->code[exc->IP + 1];
5182 4137
5183 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4138 if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
5184 { 4139 {
5185 CUR.error = FT_THROW( Stack_Overflow ); 4140 exc->error = FT_THROW( Stack_Overflow );
5186 return; 4141 return;
5187 } 4142 }
5188 4143
5189 CUR.IP += 2; 4144 exc->IP += 2;
5190 4145
5191 for ( K = 0; K < L; K++ ) 4146 for ( K = 0; K < L; K++ )
5192 args[K] = GET_ShortIns(); 4147 args[K] = GetShortIns( exc );
5193 4148
5194 CUR.step_ins = FALSE; 4149 exc->step_ins = FALSE;
5195 CUR.new_top += L; 4150 exc->new_top += L;
5196 } 4151 }
5197 4152
5198 4153
5199 /*************************************************************************/ 4154 /*************************************************************************/
5200 /* */ 4155 /* */
5201 /* PUSHB[abc]: PUSH Bytes */ 4156 /* PUSHB[abc]: PUSH Bytes */
5202 /* Opcode range: 0xB0-0xB7 */ 4157 /* Opcode range: 0xB0-0xB7 */
5203 /* Stack: --> uint32... */ 4158 /* Stack: --> uint32... */
5204 /* */ 4159 /* */
5205 static void 4160 static void
5206 Ins_PUSHB( INS_ARG ) 4161 Ins_PUSHB( TT_ExecContext exc,
4162 FT_Long* args )
5207 { 4163 {
5208 FT_UShort L, K; 4164 FT_UShort L, K;
5209 4165
5210 4166
5211 L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); 4167 L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
5212 4168
5213 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4169 if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
5214 { 4170 {
5215 CUR.error = FT_THROW( Stack_Overflow ); 4171 exc->error = FT_THROW( Stack_Overflow );
5216 return; 4172 return;
5217 } 4173 }
5218 4174
5219 for ( K = 1; K <= L; K++ ) 4175 for ( K = 1; K <= L; K++ )
5220 args[K - 1] = CUR.code[CUR.IP + K]; 4176 args[K - 1] = exc->code[exc->IP + K];
5221 } 4177 }
5222 4178
5223 4179
5224 /*************************************************************************/ 4180 /*************************************************************************/
5225 /* */ 4181 /* */
5226 /* PUSHW[abc]: PUSH Words */ 4182 /* PUSHW[abc]: PUSH Words */
5227 /* Opcode range: 0xB8-0xBF */ 4183 /* Opcode range: 0xB8-0xBF */
5228 /* Stack: --> int32... */ 4184 /* Stack: --> int32... */
5229 /* */ 4185 /* */
5230 static void 4186 static void
5231 Ins_PUSHW( INS_ARG ) 4187 Ins_PUSHW( TT_ExecContext exc,
4188 FT_Long* args )
5232 { 4189 {
5233 FT_UShort L, K; 4190 FT_UShort L, K;
5234 4191
5235 4192
5236 L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); 4193 L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
5237 4194
5238 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) 4195 if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
5239 { 4196 {
5240 CUR.error = FT_THROW( Stack_Overflow ); 4197 exc->error = FT_THROW( Stack_Overflow );
5241 return; 4198 return;
5242 } 4199 }
5243 4200
5244 CUR.IP++; 4201 exc->IP++;
5245 4202
5246 for ( K = 0; K < L; K++ ) 4203 for ( K = 0; K < L; K++ )
5247 args[K] = GET_ShortIns(); 4204 args[K] = GetShortIns( exc );
5248 4205
5249 CUR.step_ins = FALSE; 4206 exc->step_ins = FALSE;
5250 } 4207 }
5251 4208
5252 4209
5253 /*************************************************************************/ 4210 /*************************************************************************/
5254 /* */ 4211 /* */
5255 /* MANAGING THE GRAPHICS STATE */ 4212 /* MANAGING THE GRAPHICS STATE */
5256 /* */ 4213 /* */
5257 /* Instructions appear in the specs' order. */ 4214 /*************************************************************************/
5258 /* */ 4215
5259 /*************************************************************************/ 4216
5260 4217 static FT_Bool
5261 4218 Ins_SxVTL( TT_ExecContext exc,
5262 /*************************************************************************/ 4219 FT_UShort aIdx1,
4220 FT_UShort aIdx2,
4221 FT_UnitVector* Vec )
4222 {
4223 FT_Long A, B, C;
4224 FT_Vector* p1;
4225 FT_Vector* p2;
4226
4227 FT_Byte opcode = exc->opcode;
4228
4229
4230 if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
4231 BOUNDS( aIdx2, exc->zp1.n_points ) )
4232 {
4233 if ( exc->pedantic_hinting )
4234 exc->error = FT_THROW( Invalid_Reference );
4235 return FAILURE;
4236 }
4237
4238 p1 = exc->zp1.cur + aIdx2;
4239 p2 = exc->zp2.cur + aIdx1;
4240
4241 A = p1->x - p2->x;
4242 B = p1->y - p2->y;
4243
4244 /* If p1 == p2, SPvTL and SFvTL behave the same as */
4245 /* SPvTCA[X] and SFvTCA[X], respectively. */
4246 /* */
4247 /* Confirmed by Greg Hitchcock. */
4248
4249 if ( A == 0 && B == 0 )
4250 {
4251 A = 0x4000;
4252 opcode = 0;
4253 }
4254
4255 if ( ( opcode & 1 ) != 0 )
4256 {
4257 C = B; /* counter clockwise rotation */
4258 B = A;
4259 A = -C;
4260 }
4261
4262 Normalize( A, B, Vec );
4263
4264 return SUCCESS;
4265 }
4266
4267
4268 /*************************************************************************/
4269 /* */
4270 /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
4271 /* Opcode range: 0x00-0x01 */
4272 /* Stack: --> */
4273 /* */
4274 /* SPvTCA[a]: Set PVector to Coordinate Axis */
4275 /* Opcode range: 0x02-0x03 */
4276 /* Stack: --> */
4277 /* */
4278 /* SFvTCA[a]: Set FVector to Coordinate Axis */
4279 /* Opcode range: 0x04-0x05 */
4280 /* Stack: --> */
4281 /* */
4282 static void
4283 Ins_SxyTCA( TT_ExecContext exc )
4284 {
4285 FT_Short AA, BB;
4286
4287 FT_Byte opcode = exc->opcode;
4288
4289
4290 AA = (FT_Short)( ( opcode & 1 ) << 14 );
4291 BB = (FT_Short)( AA ^ 0x4000 );
4292
4293 if ( opcode < 4 )
4294 {
4295 exc->GS.projVector.x = AA;
4296 exc->GS.projVector.y = BB;
4297
4298 exc->GS.dualVector.x = AA;
4299 exc->GS.dualVector.y = BB;
4300 }
4301 else
4302 GUESS_VECTOR( projVector );
4303
4304 if ( ( opcode & 2 ) == 0 )
4305 {
4306 exc->GS.freeVector.x = AA;
4307 exc->GS.freeVector.y = BB;
4308 }
4309 else
4310 GUESS_VECTOR( freeVector );
4311
4312 Compute_Funcs( exc );
4313 }
4314
4315
4316 /*************************************************************************/
4317 /* */
4318 /* SPvTL[a]: Set PVector To Line */
4319 /* Opcode range: 0x06-0x07 */
4320 /* Stack: uint32 uint32 --> */
4321 /* */
4322 static void
4323 Ins_SPVTL( TT_ExecContext exc,
4324 FT_Long* args )
4325 {
4326 if ( Ins_SxVTL( exc,
4327 (FT_UShort)args[1],
4328 (FT_UShort)args[0],
4329 &exc->GS.projVector ) == SUCCESS )
4330 {
4331 exc->GS.dualVector = exc->GS.projVector;
4332 GUESS_VECTOR( freeVector );
4333 Compute_Funcs( exc );
4334 }
4335 }
4336
4337
4338 /*************************************************************************/
4339 /* */
4340 /* SFvTL[a]: Set FVector To Line */
4341 /* Opcode range: 0x08-0x09 */
4342 /* Stack: uint32 uint32 --> */
4343 /* */
4344 static void
4345 Ins_SFVTL( TT_ExecContext exc,
4346 FT_Long* args )
4347 {
4348 if ( Ins_SxVTL( exc,
4349 (FT_UShort)args[1],
4350 (FT_UShort)args[0],
4351 &exc->GS.freeVector ) == SUCCESS )
4352 {
4353 GUESS_VECTOR( projVector );
4354 Compute_Funcs( exc );
4355 }
4356 }
4357
4358
4359 /*************************************************************************/
4360 /* */
4361 /* SFvTPv[]: Set FVector To PVector */
4362 /* Opcode range: 0x0E */
4363 /* Stack: --> */
4364 /* */
4365 static void
4366 Ins_SFVTPV( TT_ExecContext exc )
4367 {
4368 GUESS_VECTOR( projVector );
4369 exc->GS.freeVector = exc->GS.projVector;
4370 Compute_Funcs( exc );
4371 }
4372
4373
4374 /*************************************************************************/
4375 /* */
4376 /* SPvFS[]: Set PVector From Stack */
4377 /* Opcode range: 0x0A */
4378 /* Stack: f2.14 f2.14 --> */
4379 /* */
4380 static void
4381 Ins_SPVFS( TT_ExecContext exc,
4382 FT_Long* args )
4383 {
4384 FT_Short S;
4385 FT_Long X, Y;
4386
4387
4388 /* Only use low 16bits, then sign extend */
4389 S = (FT_Short)args[1];
4390 Y = (FT_Long)S;
4391 S = (FT_Short)args[0];
4392 X = (FT_Long)S;
4393
4394 Normalize( X, Y, &exc->GS.projVector );
4395
4396 exc->GS.dualVector = exc->GS.projVector;
4397 GUESS_VECTOR( freeVector );
4398 Compute_Funcs( exc );
4399 }
4400
4401
4402 /*************************************************************************/
4403 /* */
4404 /* SFvFS[]: Set FVector From Stack */
4405 /* Opcode range: 0x0B */
4406 /* Stack: f2.14 f2.14 --> */
4407 /* */
4408 static void
4409 Ins_SFVFS( TT_ExecContext exc,
4410 FT_Long* args )
4411 {
4412 FT_Short S;
4413 FT_Long X, Y;
4414
4415
4416 /* Only use low 16bits, then sign extend */
4417 S = (FT_Short)args[1];
4418 Y = (FT_Long)S;
4419 S = (FT_Short)args[0];
4420 X = S;
4421
4422 Normalize( X, Y, &exc->GS.freeVector );
4423 GUESS_VECTOR( projVector );
4424 Compute_Funcs( exc );
4425 }
4426
4427
4428 /*************************************************************************/
4429 /* */
4430 /* GPv[]: Get Projection Vector */
4431 /* Opcode range: 0x0C */
4432 /* Stack: ef2.14 --> ef2.14 */
4433 /* */
4434 static void
4435 Ins_GPV( TT_ExecContext exc,
4436 FT_Long* args )
4437 {
4438 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
4439 if ( exc->face->unpatented_hinting )
4440 {
4441 args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
4442 args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
4443 }
4444 else
4445 {
4446 args[0] = exc->GS.projVector.x;
4447 args[1] = exc->GS.projVector.y;
4448 }
4449 #else
4450 args[0] = exc->GS.projVector.x;
4451 args[1] = exc->GS.projVector.y;
4452 #endif
4453 }
4454
4455
4456 /*************************************************************************/
4457 /* */
4458 /* GFv[]: Get Freedom Vector */
4459 /* Opcode range: 0x0D */
4460 /* Stack: ef2.14 --> ef2.14 */
4461 /* */
4462 static void
4463 Ins_GFV( TT_ExecContext exc,
4464 FT_Long* args )
4465 {
4466 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
4467 if ( exc->face->unpatented_hinting )
4468 {
4469 args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
4470 args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
4471 }
4472 else
4473 {
4474 args[0] = exc->GS.freeVector.x;
4475 args[1] = exc->GS.freeVector.y;
4476 }
4477 #else
4478 args[0] = exc->GS.freeVector.x;
4479 args[1] = exc->GS.freeVector.y;
4480 #endif
4481 }
4482
4483
4484 /*************************************************************************/
4485 /* */
4486 /* SRP0[]: Set Reference Point 0 */
4487 /* Opcode range: 0x10 */
4488 /* Stack: uint32 --> */
4489 /* */
4490 static void
4491 Ins_SRP0( TT_ExecContext exc,
4492 FT_Long* args )
4493 {
4494 exc->GS.rp0 = (FT_UShort)args[0];
4495 }
4496
4497
4498 /*************************************************************************/
4499 /* */
4500 /* SRP1[]: Set Reference Point 1 */
4501 /* Opcode range: 0x11 */
4502 /* Stack: uint32 --> */
4503 /* */
4504 static void
4505 Ins_SRP1( TT_ExecContext exc,
4506 FT_Long* args )
4507 {
4508 exc->GS.rp1 = (FT_UShort)args[0];
4509 }
4510
4511
4512 /*************************************************************************/
4513 /* */
4514 /* SRP2[]: Set Reference Point 2 */
4515 /* Opcode range: 0x12 */
4516 /* Stack: uint32 --> */
4517 /* */
4518 static void
4519 Ins_SRP2( TT_ExecContext exc,
4520 FT_Long* args )
4521 {
4522 exc->GS.rp2 = (FT_UShort)args[0];
4523 }
4524
4525
4526 /*************************************************************************/
4527 /* */
4528 /* SMD[]: Set Minimum Distance */
4529 /* Opcode range: 0x1A */
4530 /* Stack: f26.6 --> */
4531 /* */
4532 static void
4533 Ins_SMD( TT_ExecContext exc,
4534 FT_Long* args )
4535 {
4536 exc->GS.minimum_distance = args[0];
4537 }
4538
4539
4540 /*************************************************************************/
4541 /* */
4542 /* SCVTCI[]: Set Control Value Table Cut In */
4543 /* Opcode range: 0x1D */
4544 /* Stack: f26.6 --> */
4545 /* */
4546 static void
4547 Ins_SCVTCI( TT_ExecContext exc,
4548 FT_Long* args )
4549 {
4550 exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
4551 }
4552
4553
4554 /*************************************************************************/
4555 /* */
4556 /* SSWCI[]: Set Single Width Cut In */
4557 /* Opcode range: 0x1E */
4558 /* Stack: f26.6 --> */
4559 /* */
4560 static void
4561 Ins_SSWCI( TT_ExecContext exc,
4562 FT_Long* args )
4563 {
4564 exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
4565 }
4566
4567
4568 /*************************************************************************/
4569 /* */
4570 /* SSW[]: Set Single Width */
4571 /* Opcode range: 0x1F */
4572 /* Stack: int32? --> */
4573 /* */
4574 static void
4575 Ins_SSW( TT_ExecContext exc,
4576 FT_Long* args )
4577 {
4578 exc->GS.single_width_value = FT_MulFix( args[0],
4579 exc->tt_metrics.scale );
4580 }
4581
4582
4583 /*************************************************************************/
4584 /* */
4585 /* FLIPON[]: Set auto-FLIP to ON */
4586 /* Opcode range: 0x4D */
4587 /* Stack: --> */
4588 /* */
4589 static void
4590 Ins_FLIPON( TT_ExecContext exc )
4591 {
4592 exc->GS.auto_flip = TRUE;
4593 }
4594
4595
4596 /*************************************************************************/
4597 /* */
4598 /* FLIPOFF[]: Set auto-FLIP to OFF */
4599 /* Opcode range: 0x4E */
4600 /* Stack: --> */
4601 /* */
4602 static void
4603 Ins_FLIPOFF( TT_ExecContext exc )
4604 {
4605 exc->GS.auto_flip = FALSE;
4606 }
4607
4608
4609 /*************************************************************************/
4610 /* */
4611 /* SANGW[]: Set ANGle Weight */
4612 /* Opcode range: 0x7E */
4613 /* Stack: uint32 --> */
4614 /* */
4615 static void
4616 Ins_SANGW( void )
4617 {
4618 /* instruction not supported anymore */
4619 }
4620
4621
4622 /*************************************************************************/
4623 /* */
4624 /* SDB[]: Set Delta Base */
4625 /* Opcode range: 0x5E */
4626 /* Stack: uint32 --> */
4627 /* */
4628 static void
4629 Ins_SDB( TT_ExecContext exc,
4630 FT_Long* args )
4631 {
4632 exc->GS.delta_base = (FT_UShort)args[0];
4633 }
4634
4635
4636 /*************************************************************************/
4637 /* */
4638 /* SDS[]: Set Delta Shift */
4639 /* Opcode range: 0x5F */
4640 /* Stack: uint32 --> */
4641 /* */
4642 static void
4643 Ins_SDS( TT_ExecContext exc,
4644 FT_Long* args )
4645 {
4646 if ( (FT_ULong)args[0] > 6UL )
4647 exc->error = FT_THROW( Bad_Argument );
4648 else
4649 exc->GS.delta_shift = (FT_UShort)args[0];
4650 }
4651
4652
4653 /*************************************************************************/
4654 /* */
4655 /* RTHG[]: Round To Half Grid */
4656 /* Opcode range: 0x19 */
4657 /* Stack: --> */
4658 /* */
4659 static void
4660 Ins_RTHG( TT_ExecContext exc )
4661 {
4662 exc->GS.round_state = TT_Round_To_Half_Grid;
4663 exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
4664 }
4665
4666
4667 /*************************************************************************/
4668 /* */
4669 /* RTG[]: Round To Grid */
4670 /* Opcode range: 0x18 */
4671 /* Stack: --> */
4672 /* */
4673 static void
4674 Ins_RTG( TT_ExecContext exc )
4675 {
4676 exc->GS.round_state = TT_Round_To_Grid;
4677 exc->func_round = (TT_Round_Func)Round_To_Grid;
4678 }
4679
4680
4681 /*************************************************************************/
4682 /* RTDG[]: Round To Double Grid */
4683 /* Opcode range: 0x3D */
4684 /* Stack: --> */
4685 /* */
4686 static void
4687 Ins_RTDG( TT_ExecContext exc )
4688 {
4689 exc->GS.round_state = TT_Round_To_Double_Grid;
4690 exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
4691 }
4692
4693
4694 /*************************************************************************/
4695 /* RUTG[]: Round Up To Grid */
4696 /* Opcode range: 0x7C */
4697 /* Stack: --> */
4698 /* */
4699 static void
4700 Ins_RUTG( TT_ExecContext exc )
4701 {
4702 exc->GS.round_state = TT_Round_Up_To_Grid;
4703 exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
4704 }
4705
4706
4707 /*************************************************************************/
4708 /* */
4709 /* RDTG[]: Round Down To Grid */
4710 /* Opcode range: 0x7D */
4711 /* Stack: --> */
4712 /* */
4713 static void
4714 Ins_RDTG( TT_ExecContext exc )
4715 {
4716 exc->GS.round_state = TT_Round_Down_To_Grid;
4717 exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
4718 }
4719
4720
4721 /*************************************************************************/
4722 /* */
4723 /* ROFF[]: Round OFF */
4724 /* Opcode range: 0x7A */
4725 /* Stack: --> */
4726 /* */
4727 static void
4728 Ins_ROFF( TT_ExecContext exc )
4729 {
4730 exc->GS.round_state = TT_Round_Off;
4731 exc->func_round = (TT_Round_Func)Round_None;
4732 }
4733
4734
4735 /*************************************************************************/
4736 /* */
4737 /* SROUND[]: Super ROUND */
4738 /* Opcode range: 0x76 */
4739 /* Stack: Eint8 --> */
4740 /* */
4741 static void
4742 Ins_SROUND( TT_ExecContext exc,
4743 FT_Long* args )
4744 {
4745 SetSuperRound( exc, 0x4000, args[0] );
4746
4747 exc->GS.round_state = TT_Round_Super;
4748 exc->func_round = (TT_Round_Func)Round_Super;
4749 }
4750
4751
4752 /*************************************************************************/
4753 /* */
4754 /* S45ROUND[]: Super ROUND 45 degrees */
4755 /* Opcode range: 0x77 */
4756 /* Stack: uint32 --> */
4757 /* */
4758 static void
4759 Ins_S45ROUND( TT_ExecContext exc,
4760 FT_Long* args )
4761 {
4762 SetSuperRound( exc, 0x2D41, args[0] );
4763
4764 exc->GS.round_state = TT_Round_Super_45;
4765 exc->func_round = (TT_Round_Func)Round_Super_45;
4766 }
4767
4768
4769 /*************************************************************************/
5263 /* */ 4770 /* */
5264 /* GC[a]: Get Coordinate projected onto */ 4771 /* GC[a]: Get Coordinate projected onto */
5265 /* Opcode range: 0x46-0x47 */ 4772 /* Opcode range: 0x46-0x47 */
5266 /* Stack: uint32 --> f26.6 */ 4773 /* Stack: uint32 --> f26.6 */
5267 /* */ 4774 /* */
5268 /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */ 4775 /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */
5269 /* along the dual projection vector! */ 4776 /* along the dual projection vector! */
5270 /* */ 4777 /* */
5271 static void 4778 static void
5272 Ins_GC( INS_ARG ) 4779 Ins_GC( TT_ExecContext exc,
4780 FT_Long* args )
5273 { 4781 {
5274 FT_ULong L; 4782 FT_ULong L;
5275 FT_F26Dot6 R; 4783 FT_F26Dot6 R;
5276 4784
5277 4785
5278 L = (FT_ULong)args[0]; 4786 L = (FT_ULong)args[0];
5279 4787
5280 if ( BOUNDSL( L, CUR.zp2.n_points ) ) 4788 if ( BOUNDSL( L, exc->zp2.n_points ) )
5281 { 4789 {
5282 if ( CUR.pedantic_hinting ) 4790 if ( exc->pedantic_hinting )
5283 CUR.error = FT_THROW( Invalid_Reference ); 4791 exc->error = FT_THROW( Invalid_Reference );
5284 R = 0; 4792 R = 0;
5285 } 4793 }
5286 else 4794 else
5287 { 4795 {
5288 if ( CUR.opcode & 1 ) 4796 if ( exc->opcode & 1 )
5289 R = CUR_fast_dualproj( &CUR.zp2.org[L] ); 4797 R = FAST_DUALPROJ( &exc->zp2.org[L] );
5290 else 4798 else
5291 R = CUR_fast_project( &CUR.zp2.cur[L] ); 4799 R = FAST_PROJECT( &exc->zp2.cur[L] );
5292 } 4800 }
5293 4801
5294 args[0] = R; 4802 args[0] = R;
5295 } 4803 }
5296 4804
5297 4805
5298 /*************************************************************************/ 4806 /*************************************************************************/
5299 /* */ 4807 /* */
5300 /* SCFS[]: Set Coordinate From Stack */ 4808 /* SCFS[]: Set Coordinate From Stack */
5301 /* Opcode range: 0x48 */ 4809 /* Opcode range: 0x48 */
5302 /* Stack: f26.6 uint32 --> */ 4810 /* Stack: f26.6 uint32 --> */
5303 /* */ 4811 /* */
5304 /* Formula: */ 4812 /* Formula: */
5305 /* */ 4813 /* */
5306 /* OA := OA + ( value - OA.p )/( f.p ) * f */ 4814 /* OA := OA + ( value - OA.p )/( f.p ) * f */
5307 /* */ 4815 /* */
5308 static void 4816 static void
5309 Ins_SCFS( INS_ARG ) 4817 Ins_SCFS( TT_ExecContext exc,
4818 FT_Long* args )
5310 { 4819 {
5311 FT_Long K; 4820 FT_Long K;
5312 FT_UShort L; 4821 FT_UShort L;
5313 4822
5314 4823
5315 L = (FT_UShort)args[0]; 4824 L = (FT_UShort)args[0];
5316 4825
5317 if ( BOUNDS( L, CUR.zp2.n_points ) ) 4826 if ( BOUNDS( L, exc->zp2.n_points ) )
5318 { 4827 {
5319 if ( CUR.pedantic_hinting ) 4828 if ( exc->pedantic_hinting )
5320 CUR.error = FT_THROW( Invalid_Reference ); 4829 exc->error = FT_THROW( Invalid_Reference );
5321 return; 4830 return;
5322 } 4831 }
5323 4832
5324 K = CUR_fast_project( &CUR.zp2.cur[L] ); 4833 K = FAST_PROJECT( &exc->zp2.cur[L] );
5325 4834
5326 CUR_Func_move( &CUR.zp2, L, args[1] - K ); 4835 exc->func_move( exc, &exc->zp2, L, args[1] - K );
5327 4836
5328 /* UNDOCUMENTED! The MS rasterizer does that with */ 4837 /* UNDOCUMENTED! The MS rasterizer does that with */
5329 /* twilight points (confirmed by Greg Hitchcock) */ 4838 /* twilight points (confirmed by Greg Hitchcock) */
5330 if ( CUR.GS.gep2 == 0 ) 4839 if ( exc->GS.gep2 == 0 )
5331 CUR.zp2.org[L] = CUR.zp2.cur[L]; 4840 exc->zp2.org[L] = exc->zp2.cur[L];
5332 } 4841 }
5333 4842
5334 4843
5335 /*************************************************************************/ 4844 /*************************************************************************/
5336 /* */ 4845 /* */
5337 /* MD[a]: Measure Distance */ 4846 /* MD[a]: Measure Distance */
5338 /* Opcode range: 0x49-0x4A */ 4847 /* Opcode range: 0x49-0x4A */
5339 /* Stack: uint32 uint32 --> f26.6 */ 4848 /* Stack: uint32 uint32 --> f26.6 */
5340 /* */ 4849 /* */
5341 /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */ 4850 /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */
5342 /* the dual projection vector. */ 4851 /* the dual projection vector. */
5343 /* */ 4852 /* */
5344 /* XXX: UNDOCUMENTED: Flag attributes are inverted! */ 4853 /* XXX: UNDOCUMENTED: Flag attributes are inverted! */
5345 /* 0 => measure distance in original outline */ 4854 /* 0 => measure distance in original outline */
5346 /* 1 => measure distance in grid-fitted outline */ 4855 /* 1 => measure distance in grid-fitted outline */
5347 /* */ 4856 /* */
5348 /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ 4857 /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */
5349 /* */ 4858 /* */
5350 static void 4859 static void
5351 Ins_MD( INS_ARG ) 4860 Ins_MD( TT_ExecContext exc,
4861 FT_Long* args )
5352 { 4862 {
5353 FT_UShort K, L; 4863 FT_UShort K, L;
5354 FT_F26Dot6 D; 4864 FT_F26Dot6 D;
5355 4865
5356 4866
5357 K = (FT_UShort)args[1]; 4867 K = (FT_UShort)args[1];
5358 L = (FT_UShort)args[0]; 4868 L = (FT_UShort)args[0];
5359 4869
5360 if ( BOUNDS( L, CUR.zp0.n_points ) || 4870 if ( BOUNDS( L, exc->zp0.n_points ) ||
5361 BOUNDS( K, CUR.zp1.n_points ) ) 4871 BOUNDS( K, exc->zp1.n_points ) )
5362 { 4872 {
5363 if ( CUR.pedantic_hinting ) 4873 if ( exc->pedantic_hinting )
5364 CUR.error = FT_THROW( Invalid_Reference ); 4874 exc->error = FT_THROW( Invalid_Reference );
5365 D = 0; 4875 D = 0;
5366 } 4876 }
5367 else 4877 else
5368 { 4878 {
5369 if ( CUR.opcode & 1 ) 4879 if ( exc->opcode & 1 )
5370 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); 4880 D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
5371 else 4881 else
5372 { 4882 {
5373 /* XXX: UNDOCUMENTED: twilight zone special case */ 4883 /* XXX: UNDOCUMENTED: twilight zone special case */
5374 4884
5375 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) 4885 if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
5376 { 4886 {
5377 FT_Vector* vec1 = CUR.zp0.org + L; 4887 FT_Vector* vec1 = exc->zp0.org + L;
5378 FT_Vector* vec2 = CUR.zp1.org + K; 4888 FT_Vector* vec2 = exc->zp1.org + K;
5379 4889
5380 4890
5381 D = CUR_Func_dualproj( vec1, vec2 ); 4891 D = DUALPROJ( vec1, vec2 );
5382 } 4892 }
5383 else 4893 else
5384 { 4894 {
5385 FT_Vector* vec1 = CUR.zp0.orus + L; 4895 FT_Vector* vec1 = exc->zp0.orus + L;
5386 FT_Vector* vec2 = CUR.zp1.orus + K; 4896 FT_Vector* vec2 = exc->zp1.orus + K;
5387 4897
5388 4898
5389 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) 4899 if ( exc->metrics.x_scale == exc->metrics.y_scale )
5390 { 4900 {
5391 /* this should be faster */ 4901 /* this should be faster */
5392 D = CUR_Func_dualproj( vec1, vec2 ); 4902 D = DUALPROJ( vec1, vec2 );
5393 D = FT_MulFix( D, CUR.metrics.x_scale ); 4903 D = FT_MulFix( D, exc->metrics.x_scale );
5394 } 4904 }
5395 else 4905 else
5396 { 4906 {
5397 FT_Vector vec; 4907 FT_Vector vec;
5398 4908
5399 4909
5400 vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); 4910 vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
5401 vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); 4911 vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
5402 4912
5403 D = CUR_fast_dualproj( &vec ); 4913 D = FAST_DUALPROJ( &vec );
5404 } 4914 }
5405 } 4915 }
5406 } 4916 }
5407 } 4917 }
5408 4918
5409 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 4919 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
5410 /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ 4920 /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
5411 if ( SUBPIXEL_HINTING && 4921 if ( SUBPIXEL_HINTING &&
5412 CUR.ignore_x_mode && FT_ABS( D ) == 64 ) 4922 exc->ignore_x_mode &&
4923 FT_ABS( D ) == 64 )
5413 D += 1; 4924 D += 1;
5414 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 4925 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
5415 4926
5416 args[0] = D; 4927 args[0] = D;
5417 } 4928 }
5418 4929
5419 4930
5420 /*************************************************************************/ 4931 /*************************************************************************/
5421 /* */ 4932 /* */
5422 /* SDPVTL[a]: Set Dual PVector to Line */ 4933 /* SDPvTL[a]: Set Dual PVector to Line */
5423 /* Opcode range: 0x86-0x87 */ 4934 /* Opcode range: 0x86-0x87 */
5424 /* Stack: uint32 uint32 --> */ 4935 /* Stack: uint32 uint32 --> */
5425 /* */ 4936 /* */
5426 static void 4937 static void
5427 Ins_SDPVTL( INS_ARG ) 4938 Ins_SDPVTL( TT_ExecContext exc,
4939 FT_Long* args )
5428 { 4940 {
5429 FT_Long A, B, C; 4941 FT_Long A, B, C;
5430 FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ 4942 FT_UShort p1, p2; /* was FT_Int in pas type ERROR */
5431 FT_Int aOpc = CUR.opcode; 4943
4944 FT_Byte opcode = exc->opcode;
5432 4945
5433 4946
5434 p1 = (FT_UShort)args[1]; 4947 p1 = (FT_UShort)args[1];
5435 p2 = (FT_UShort)args[0]; 4948 p2 = (FT_UShort)args[0];
5436 4949
5437 if ( BOUNDS( p2, CUR.zp1.n_points ) || 4950 if ( BOUNDS( p2, exc->zp1.n_points ) ||
5438 BOUNDS( p1, CUR.zp2.n_points ) ) 4951 BOUNDS( p1, exc->zp2.n_points ) )
5439 { 4952 {
5440 if ( CUR.pedantic_hinting ) 4953 if ( exc->pedantic_hinting )
5441 CUR.error = FT_THROW( Invalid_Reference ); 4954 exc->error = FT_THROW( Invalid_Reference );
5442 return; 4955 return;
5443 } 4956 }
5444 4957
5445 { 4958 {
5446 FT_Vector* v1 = CUR.zp1.org + p2; 4959 FT_Vector* v1 = exc->zp1.org + p2;
5447 FT_Vector* v2 = CUR.zp2.org + p1; 4960 FT_Vector* v2 = exc->zp2.org + p1;
5448 4961
5449 4962
5450 A = v1->x - v2->x; 4963 A = v1->x - v2->x;
5451 B = v1->y - v2->y; 4964 B = v1->y - v2->y;
5452 4965
5453 /* If v1 == v2, SDPVTL behaves the same as */ 4966 /* If v1 == v2, SDPvTL behaves the same as */
5454 /* SVTCA[X], respectively. */ 4967 /* SVTCA[X], respectively. */
5455 /* */ 4968 /* */
5456 /* Confirmed by Greg Hitchcock. */ 4969 /* Confirmed by Greg Hitchcock. */
5457 4970
5458 if ( A == 0 && B == 0 ) 4971 if ( A == 0 && B == 0 )
5459 { 4972 {
5460 A = 0x4000; 4973 A = 0x4000;
5461 aOpc = 0; 4974 opcode = 0;
5462 } 4975 }
5463 } 4976 }
5464 4977
5465 if ( ( aOpc & 1 ) != 0 ) 4978 if ( ( opcode & 1 ) != 0 )
5466 { 4979 {
5467 C = B; /* counter clockwise rotation */ 4980 C = B; /* counter clockwise rotation */
5468 B = A; 4981 B = A;
5469 A = -C; 4982 A = -C;
5470 } 4983 }
5471 4984
5472 NORMalize( A, B, &CUR.GS.dualVector ); 4985 Normalize( A, B, &exc->GS.dualVector );
5473 4986
5474 { 4987 {
5475 FT_Vector* v1 = CUR.zp1.cur + p2; 4988 FT_Vector* v1 = exc->zp1.cur + p2;
5476 FT_Vector* v2 = CUR.zp2.cur + p1; 4989 FT_Vector* v2 = exc->zp2.cur + p1;
5477 4990
5478 4991
5479 A = v1->x - v2->x; 4992 A = v1->x - v2->x;
5480 B = v1->y - v2->y; 4993 B = v1->y - v2->y;
5481 4994
5482 if ( A == 0 && B == 0 ) 4995 if ( A == 0 && B == 0 )
5483 { 4996 {
5484 A = 0x4000; 4997 A = 0x4000;
5485 aOpc = 0; 4998 opcode = 0;
5486 } 4999 }
5487 } 5000 }
5488 5001
5489 if ( ( aOpc & 1 ) != 0 ) 5002 if ( ( opcode & 1 ) != 0 )
5490 { 5003 {
5491 C = B; /* counter clockwise rotation */ 5004 C = B; /* counter clockwise rotation */
5492 B = A; 5005 B = A;
5493 A = -C; 5006 A = -C;
5494 } 5007 }
5495 5008
5496 NORMalize( A, B, &CUR.GS.projVector ); 5009 Normalize( A, B, &exc->GS.projVector );
5497
5498 GUESS_VECTOR( freeVector ); 5010 GUESS_VECTOR( freeVector );
5499 5011 Compute_Funcs( exc );
5500 COMPUTE_Funcs();
5501 } 5012 }
5502 5013
5503 5014
5504 /*************************************************************************/ 5015 /*************************************************************************/
5505 /* */ 5016 /* */
5506 /* SZP0[]: Set Zone Pointer 0 */ 5017 /* SZP0[]: Set Zone Pointer 0 */
5507 /* Opcode range: 0x13 */ 5018 /* Opcode range: 0x13 */
5508 /* Stack: uint32 --> */ 5019 /* Stack: uint32 --> */
5509 /* */ 5020 /* */
5510 static void 5021 static void
5511 Ins_SZP0( INS_ARG ) 5022 Ins_SZP0( TT_ExecContext exc,
5023 FT_Long* args )
5512 { 5024 {
5513 switch ( (FT_Int)args[0] ) 5025 switch ( (FT_Int)args[0] )
5514 { 5026 {
5515 case 0: 5027 case 0:
5516 CUR.zp0 = CUR.twilight; 5028 exc->zp0 = exc->twilight;
5517 break; 5029 break;
5518 5030
5519 case 1: 5031 case 1:
5520 CUR.zp0 = CUR.pts; 5032 exc->zp0 = exc->pts;
5521 break; 5033 break;
5522 5034
5523 default: 5035 default:
5524 if ( CUR.pedantic_hinting ) 5036 if ( exc->pedantic_hinting )
5525 CUR.error = FT_THROW( Invalid_Reference ); 5037 exc->error = FT_THROW( Invalid_Reference );
5526 return; 5038 return;
5527 } 5039 }
5528 5040
5529 CUR.GS.gep0 = (FT_UShort)args[0]; 5041 exc->GS.gep0 = (FT_UShort)args[0];
5530 } 5042 }
5531 5043
5532 5044
5533 /*************************************************************************/ 5045 /*************************************************************************/
5534 /* */ 5046 /* */
5535 /* SZP1[]: Set Zone Pointer 1 */ 5047 /* SZP1[]: Set Zone Pointer 1 */
5536 /* Opcode range: 0x14 */ 5048 /* Opcode range: 0x14 */
5537 /* Stack: uint32 --> */ 5049 /* Stack: uint32 --> */
5538 /* */ 5050 /* */
5539 static void 5051 static void
5540 Ins_SZP1( INS_ARG ) 5052 Ins_SZP1( TT_ExecContext exc,
5053 FT_Long* args )
5541 { 5054 {
5542 switch ( (FT_Int)args[0] ) 5055 switch ( (FT_Int)args[0] )
5543 { 5056 {
5544 case 0: 5057 case 0:
5545 CUR.zp1 = CUR.twilight; 5058 exc->zp1 = exc->twilight;
5546 break; 5059 break;
5547 5060
5548 case 1: 5061 case 1:
5549 CUR.zp1 = CUR.pts; 5062 exc->zp1 = exc->pts;
5550 break; 5063 break;
5551 5064
5552 default: 5065 default:
5553 if ( CUR.pedantic_hinting ) 5066 if ( exc->pedantic_hinting )
5554 CUR.error = FT_THROW( Invalid_Reference ); 5067 exc->error = FT_THROW( Invalid_Reference );
5555 return; 5068 return;
5556 } 5069 }
5557 5070
5558 CUR.GS.gep1 = (FT_UShort)args[0]; 5071 exc->GS.gep1 = (FT_UShort)args[0];
5559 } 5072 }
5560 5073
5561 5074
5562 /*************************************************************************/ 5075 /*************************************************************************/
5563 /* */ 5076 /* */
5564 /* SZP2[]: Set Zone Pointer 2 */ 5077 /* SZP2[]: Set Zone Pointer 2 */
5565 /* Opcode range: 0x15 */ 5078 /* Opcode range: 0x15 */
5566 /* Stack: uint32 --> */ 5079 /* Stack: uint32 --> */
5567 /* */ 5080 /* */
5568 static void 5081 static void
5569 Ins_SZP2( INS_ARG ) 5082 Ins_SZP2( TT_ExecContext exc,
5083 FT_Long* args )
5570 { 5084 {
5571 switch ( (FT_Int)args[0] ) 5085 switch ( (FT_Int)args[0] )
5572 { 5086 {
5573 case 0: 5087 case 0:
5574 CUR.zp2 = CUR.twilight; 5088 exc->zp2 = exc->twilight;
5575 break; 5089 break;
5576 5090
5577 case 1: 5091 case 1:
5578 CUR.zp2 = CUR.pts; 5092 exc->zp2 = exc->pts;
5579 break; 5093 break;
5580 5094
5581 default: 5095 default:
5582 if ( CUR.pedantic_hinting ) 5096 if ( exc->pedantic_hinting )
5583 CUR.error = FT_THROW( Invalid_Reference ); 5097 exc->error = FT_THROW( Invalid_Reference );
5584 return; 5098 return;
5585 } 5099 }
5586 5100
5587 CUR.GS.gep2 = (FT_UShort)args[0]; 5101 exc->GS.gep2 = (FT_UShort)args[0];
5588 } 5102 }
5589 5103
5590 5104
5591 /*************************************************************************/ 5105 /*************************************************************************/
5592 /* */ 5106 /* */
5593 /* SZPS[]: Set Zone PointerS */ 5107 /* SZPS[]: Set Zone PointerS */
5594 /* Opcode range: 0x16 */ 5108 /* Opcode range: 0x16 */
5595 /* Stack: uint32 --> */ 5109 /* Stack: uint32 --> */
5596 /* */ 5110 /* */
5597 static void 5111 static void
5598 Ins_SZPS( INS_ARG ) 5112 Ins_SZPS( TT_ExecContext exc,
5113 FT_Long* args )
5599 { 5114 {
5600 switch ( (FT_Int)args[0] ) 5115 switch ( (FT_Int)args[0] )
5601 { 5116 {
5602 case 0: 5117 case 0:
5603 CUR.zp0 = CUR.twilight; 5118 exc->zp0 = exc->twilight;
5604 break; 5119 break;
5605 5120
5606 case 1: 5121 case 1:
5607 CUR.zp0 = CUR.pts; 5122 exc->zp0 = exc->pts;
5608 break; 5123 break;
5609 5124
5610 default: 5125 default:
5611 if ( CUR.pedantic_hinting ) 5126 if ( exc->pedantic_hinting )
5612 CUR.error = FT_THROW( Invalid_Reference ); 5127 exc->error = FT_THROW( Invalid_Reference );
5613 return; 5128 return;
5614 } 5129 }
5615 5130
5616 CUR.zp1 = CUR.zp0; 5131 exc->zp1 = exc->zp0;
5617 CUR.zp2 = CUR.zp0; 5132 exc->zp2 = exc->zp0;
5618 5133
5619 CUR.GS.gep0 = (FT_UShort)args[0]; 5134 exc->GS.gep0 = (FT_UShort)args[0];
5620 CUR.GS.gep1 = (FT_UShort)args[0]; 5135 exc->GS.gep1 = (FT_UShort)args[0];
5621 CUR.GS.gep2 = (FT_UShort)args[0]; 5136 exc->GS.gep2 = (FT_UShort)args[0];
5622 } 5137 }
5623 5138
5624 5139
5625 /*************************************************************************/ 5140 /*************************************************************************/
5626 /* */ 5141 /* */
5627 /* INSTCTRL[]: INSTruction ConTRoL */ 5142 /* INSTCTRL[]: INSTruction ConTRoL */
5628 /* Opcode range: 0x8e */ 5143 /* Opcode range: 0x8E */
5629 /* Stack: int32 int32 --> */ 5144 /* Stack: int32 int32 --> */
5630 /* */ 5145 /* */
5631 static void 5146 static void
5632 Ins_INSTCTRL( INS_ARG ) 5147 Ins_INSTCTRL( TT_ExecContext exc,
5148 FT_Long* args )
5633 { 5149 {
5634 FT_Long K, L; 5150 FT_ULong K, L, Kf;
5635 5151
5636 5152
5637 K = args[1]; 5153 K = (FT_ULong)args[1];
5638 L = args[0]; 5154 L = (FT_ULong)args[0];
5639 5155
5640 if ( K < 1 || K > 2 ) 5156 /* selector values cannot be `OR'ed; */
5157 /* they are indices starting with index 1, not flags */
5158 if ( K < 1 || K > 3 )
5641 { 5159 {
5642 if ( CUR.pedantic_hinting ) 5160 if ( exc->pedantic_hinting )
5643 CUR.error = FT_THROW( Invalid_Reference ); 5161 exc->error = FT_THROW( Invalid_Reference );
5644 return; 5162 return;
5645 } 5163 }
5646 5164
5165 /* convert index to flag value */
5166 Kf = 1 << ( K - 1 );
5167
5647 if ( L != 0 ) 5168 if ( L != 0 )
5648 L = K; 5169 {
5170 /* arguments to selectors look like flag values */
5171 if ( L != Kf )
5172 {
5173 if ( exc->pedantic_hinting )
5174 exc->error = FT_THROW( Invalid_Reference );
5175 return;
5176 }
5177 }
5649 5178
5650 CUR.GS.instruct_control = FT_BOOL( 5179 exc->GS.instruct_control &= ~(FT_Byte)Kf;
5651 ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); 5180 exc->GS.instruct_control |= (FT_Byte)L;
5181
5182 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
5183 /* INSTCTRL modifying flag 3 also has an effect */
5184 /* outside of the CVT program */
5185 if ( K == 3 )
5186 exc->ignore_x_mode = FT_BOOL( L == 4 );
5187 #endif
5652 } 5188 }
5653 5189
5654 5190
5655 /*************************************************************************/ 5191 /*************************************************************************/
5656 /* */ 5192 /* */
5657 /* SCANCTRL[]: SCAN ConTRoL */ 5193 /* SCANCTRL[]: SCAN ConTRoL */
5658 /* Opcode range: 0x85 */ 5194 /* Opcode range: 0x85 */
5659 /* Stack: uint32? --> */ 5195 /* Stack: uint32? --> */
5660 /* */ 5196 /* */
5661 static void 5197 static void
5662 Ins_SCANCTRL( INS_ARG ) 5198 Ins_SCANCTRL( TT_ExecContext exc,
5199 FT_Long* args )
5663 { 5200 {
5664 FT_Int A; 5201 FT_Int A;
5665 5202
5666 5203
5667 /* Get Threshold */ 5204 /* Get Threshold */
5668 A = (FT_Int)( args[0] & 0xFF ); 5205 A = (FT_Int)( args[0] & 0xFF );
5669 5206
5670 if ( A == 0xFF ) 5207 if ( A == 0xFF )
5671 { 5208 {
5672 CUR.GS.scan_control = TRUE; 5209 exc->GS.scan_control = TRUE;
5673 return; 5210 return;
5674 } 5211 }
5675 else if ( A == 0 ) 5212 else if ( A == 0 )
5676 { 5213 {
5677 CUR.GS.scan_control = FALSE; 5214 exc->GS.scan_control = FALSE;
5678 return; 5215 return;
5679 } 5216 }
5680 5217
5681 if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) 5218 if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
5682 CUR.GS.scan_control = TRUE; 5219 exc->GS.scan_control = TRUE;
5683 5220
5684 if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) 5221 if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
5685 CUR.GS.scan_control = TRUE; 5222 exc->GS.scan_control = TRUE;
5686 5223
5687 if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) 5224 if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
5688 CUR.GS.scan_control = TRUE; 5225 exc->GS.scan_control = TRUE;
5689 5226
5690 if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) 5227 if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
5691 CUR.GS.scan_control = FALSE; 5228 exc->GS.scan_control = FALSE;
5692 5229
5693 if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) 5230 if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
5694 CUR.GS.scan_control = FALSE; 5231 exc->GS.scan_control = FALSE;
5695 5232
5696 if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) 5233 if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
5697 CUR.GS.scan_control = FALSE; 5234 exc->GS.scan_control = FALSE;
5698 } 5235 }
5699 5236
5700 5237
5701 /*************************************************************************/ 5238 /*************************************************************************/
5702 /* */ 5239 /* */
5703 /* SCANTYPE[]: SCAN TYPE */ 5240 /* SCANTYPE[]: SCAN TYPE */
5704 /* Opcode range: 0x8D */ 5241 /* Opcode range: 0x8D */
5705 /* Stack: uint32? --> */ 5242 /* Stack: uint32? --> */
5706 /* */ 5243 /* */
5707 static void 5244 static void
5708 Ins_SCANTYPE( INS_ARG ) 5245 Ins_SCANTYPE( TT_ExecContext exc,
5246 FT_Long* args )
5709 { 5247 {
5710 if ( args[0] >= 0 ) 5248 if ( args[0] >= 0 )
5711 CUR.GS.scan_type = (FT_Int)args[0]; 5249 exc->GS.scan_type = (FT_Int)args[0];
5712 } 5250 }
5713 5251
5714 5252
5715 /*************************************************************************/ 5253 /*************************************************************************/
5716 /* */ 5254 /* */
5717 /* MANAGING OUTLINES */ 5255 /* MANAGING OUTLINES */
5718 /* */ 5256 /* */
5719 /* Instructions appear in the specification's order. */
5720 /* */
5721 /*************************************************************************/ 5257 /*************************************************************************/
5722 5258
5723 5259
5724 /*************************************************************************/ 5260 /*************************************************************************/
5725 /* */ 5261 /* */
5726 /* FLIPPT[]: FLIP PoinT */ 5262 /* FLIPPT[]: FLIP PoinT */
5727 /* Opcode range: 0x80 */ 5263 /* Opcode range: 0x80 */
5728 /* Stack: uint32... --> */ 5264 /* Stack: uint32... --> */
5729 /* */ 5265 /* */
5730 static void 5266 static void
5731 Ins_FLIPPT( INS_ARG ) 5267 Ins_FLIPPT( TT_ExecContext exc )
5732 { 5268 {
5733 FT_UShort point; 5269 FT_UShort point;
5734 5270
5735 FT_UNUSED_ARG;
5736 5271
5737 5272 if ( exc->top < exc->GS.loop )
5738 if ( CUR.top < CUR.GS.loop )
5739 { 5273 {
5740 if ( CUR.pedantic_hinting ) 5274 if ( exc->pedantic_hinting )
5741 CUR.error = FT_THROW( Too_Few_Arguments ); 5275 exc->error = FT_THROW( Too_Few_Arguments );
5742 goto Fail; 5276 goto Fail;
5743 } 5277 }
5744 5278
5745 while ( CUR.GS.loop > 0 ) 5279 while ( exc->GS.loop > 0 )
5746 { 5280 {
5747 CUR.args--; 5281 exc->args--;
5748 5282
5749 point = (FT_UShort)CUR.stack[CUR.args]; 5283 point = (FT_UShort)exc->stack[exc->args];
5750 5284
5751 if ( BOUNDS( point, CUR.pts.n_points ) ) 5285 if ( BOUNDS( point, exc->pts.n_points ) )
5752 { 5286 {
5753 if ( CUR.pedantic_hinting ) 5287 if ( exc->pedantic_hinting )
5754 { 5288 {
5755 CUR.error = FT_THROW( Invalid_Reference ); 5289 exc->error = FT_THROW( Invalid_Reference );
5756 return; 5290 return;
5757 } 5291 }
5758 } 5292 }
5759 else 5293 else
5760 CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; 5294 exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
5761 5295
5762 CUR.GS.loop--; 5296 exc->GS.loop--;
5763 } 5297 }
5764 5298
5765 Fail: 5299 Fail:
5766 CUR.GS.loop = 1; 5300 exc->GS.loop = 1;
5767 CUR.new_top = CUR.args; 5301 exc->new_top = exc->args;
5768 } 5302 }
5769 5303
5770 5304
5771 /*************************************************************************/ 5305 /*************************************************************************/
5772 /* */ 5306 /* */
5773 /* FLIPRGON[]: FLIP RanGe ON */ 5307 /* FLIPRGON[]: FLIP RanGe ON */
5774 /* Opcode range: 0x81 */ 5308 /* Opcode range: 0x81 */
5775 /* Stack: uint32 uint32 --> */ 5309 /* Stack: uint32 uint32 --> */
5776 /* */ 5310 /* */
5777 static void 5311 static void
5778 Ins_FLIPRGON( INS_ARG ) 5312 Ins_FLIPRGON( TT_ExecContext exc,
5313 FT_Long* args )
5779 { 5314 {
5780 FT_UShort I, K, L; 5315 FT_UShort I, K, L;
5781 5316
5782 5317
5783 K = (FT_UShort)args[1]; 5318 K = (FT_UShort)args[1];
5784 L = (FT_UShort)args[0]; 5319 L = (FT_UShort)args[0];
5785 5320
5786 if ( BOUNDS( K, CUR.pts.n_points ) || 5321 if ( BOUNDS( K, exc->pts.n_points ) ||
5787 BOUNDS( L, CUR.pts.n_points ) ) 5322 BOUNDS( L, exc->pts.n_points ) )
5788 { 5323 {
5789 if ( CUR.pedantic_hinting ) 5324 if ( exc->pedantic_hinting )
5790 CUR.error = FT_THROW( Invalid_Reference ); 5325 exc->error = FT_THROW( Invalid_Reference );
5791 return; 5326 return;
5792 } 5327 }
5793 5328
5794 for ( I = L; I <= K; I++ ) 5329 for ( I = L; I <= K; I++ )
5795 CUR.pts.tags[I] |= FT_CURVE_TAG_ON; 5330 exc->pts.tags[I] |= FT_CURVE_TAG_ON;
5796 } 5331 }
5797 5332
5798 5333
5799 /*************************************************************************/ 5334 /*************************************************************************/
5800 /* */ 5335 /* */
5801 /* FLIPRGOFF: FLIP RanGe OFF */ 5336 /* FLIPRGOFF: FLIP RanGe OFF */
5802 /* Opcode range: 0x82 */ 5337 /* Opcode range: 0x82 */
5803 /* Stack: uint32 uint32 --> */ 5338 /* Stack: uint32 uint32 --> */
5804 /* */ 5339 /* */
5805 static void 5340 static void
5806 Ins_FLIPRGOFF( INS_ARG ) 5341 Ins_FLIPRGOFF( TT_ExecContext exc,
5342 FT_Long* args )
5807 { 5343 {
5808 FT_UShort I, K, L; 5344 FT_UShort I, K, L;
5809 5345
5810 5346
5811 K = (FT_UShort)args[1]; 5347 K = (FT_UShort)args[1];
5812 L = (FT_UShort)args[0]; 5348 L = (FT_UShort)args[0];
5813 5349
5814 if ( BOUNDS( K, CUR.pts.n_points ) || 5350 if ( BOUNDS( K, exc->pts.n_points ) ||
5815 BOUNDS( L, CUR.pts.n_points ) ) 5351 BOUNDS( L, exc->pts.n_points ) )
5816 { 5352 {
5817 if ( CUR.pedantic_hinting ) 5353 if ( exc->pedantic_hinting )
5818 CUR.error = FT_THROW( Invalid_Reference ); 5354 exc->error = FT_THROW( Invalid_Reference );
5819 return; 5355 return;
5820 } 5356 }
5821 5357
5822 for ( I = L; I <= K; I++ ) 5358 for ( I = L; I <= K; I++ )
5823 CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; 5359 exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
5824 } 5360 }
5825 5361
5826 5362
5827 static FT_Bool 5363 static FT_Bool
5828 Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, 5364 Compute_Point_Displacement( TT_ExecContext exc,
5829 FT_F26Dot6* y, 5365 FT_F26Dot6* x,
5830 TT_GlyphZone zone, 5366 FT_F26Dot6* y,
5831 FT_UShort* refp ) 5367 TT_GlyphZone zone,
5368 FT_UShort* refp )
5832 { 5369 {
5833 TT_GlyphZoneRec zp; 5370 TT_GlyphZoneRec zp;
5834 FT_UShort p; 5371 FT_UShort p;
5835 FT_F26Dot6 d; 5372 FT_F26Dot6 d;
5836 5373
5837 5374
5838 if ( CUR.opcode & 1 ) 5375 if ( exc->opcode & 1 )
5839 { 5376 {
5840 zp = CUR.zp0; 5377 zp = exc->zp0;
5841 p = CUR.GS.rp1; 5378 p = exc->GS.rp1;
5842 } 5379 }
5843 else 5380 else
5844 { 5381 {
5845 zp = CUR.zp1; 5382 zp = exc->zp1;
5846 p = CUR.GS.rp2; 5383 p = exc->GS.rp2;
5847 } 5384 }
5848 5385
5849 if ( BOUNDS( p, zp.n_points ) ) 5386 if ( BOUNDS( p, zp.n_points ) )
5850 { 5387 {
5851 if ( CUR.pedantic_hinting ) 5388 if ( exc->pedantic_hinting )
5852 CUR.error = FT_THROW( Invalid_Reference ); 5389 exc->error = FT_THROW( Invalid_Reference );
5853 *refp = 0; 5390 *refp = 0;
5854 return FAILURE; 5391 return FAILURE;
5855 } 5392 }
5856 5393
5857 *zone = zp; 5394 *zone = zp;
5858 *refp = p; 5395 *refp = p;
5859 5396
5860 d = CUR_Func_project( zp.cur + p, zp.org + p ); 5397 d = PROJECT( zp.cur + p, zp.org + p );
5861 5398
5862 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 5399 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
5863 if ( CUR.face->unpatented_hinting ) 5400 if ( exc->face->unpatented_hinting )
5864 { 5401 {
5865 if ( CUR.GS.both_x_axis ) 5402 if ( exc->GS.both_x_axis )
5866 { 5403 {
5867 *x = d; 5404 *x = d;
5868 *y = 0; 5405 *y = 0;
5869 } 5406 }
5870 else 5407 else
5871 { 5408 {
5872 *x = 0; 5409 *x = 0;
5873 *y = d; 5410 *y = d;
5874 } 5411 }
5875 } 5412 }
5876 else 5413 else
5877 #endif 5414 #endif
5878 { 5415 {
5879 *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); 5416 *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
5880 *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); 5417 *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
5881 } 5418 }
5882 5419
5883 return SUCCESS; 5420 return SUCCESS;
5884 } 5421 }
5885 5422
5886 5423
5887 static void 5424 static void
5888 Move_Zp2_Point( EXEC_OP_ FT_UShort point, 5425 Move_Zp2_Point( TT_ExecContext exc,
5889 FT_F26Dot6 dx, 5426 FT_UShort point,
5890 FT_F26Dot6 dy, 5427 FT_F26Dot6 dx,
5891 FT_Bool touch ) 5428 FT_F26Dot6 dy,
5429 FT_Bool touch )
5892 { 5430 {
5893 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 5431 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
5894 if ( CUR.face->unpatented_hinting ) 5432 if ( exc->face->unpatented_hinting )
5895 { 5433 {
5896 if ( CUR.GS.both_x_axis ) 5434 if ( exc->GS.both_x_axis )
5897 { 5435 {
5898 CUR.zp2.cur[point].x += dx; 5436 exc->zp2.cur[point].x += dx;
5899 if ( touch ) 5437 if ( touch )
5900 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; 5438 exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
5901 } 5439 }
5902 else 5440 else
5903 { 5441 {
5904 CUR.zp2.cur[point].y += dy; 5442 exc->zp2.cur[point].y += dy;
5905 if ( touch ) 5443 if ( touch )
5906 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; 5444 exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
5907 } 5445 }
5908 return; 5446 return;
5909 } 5447 }
5910 #endif 5448 #endif
5911 5449
5912 if ( CUR.GS.freeVector.x != 0 ) 5450 if ( exc->GS.freeVector.x != 0 )
5913 { 5451 {
5914 CUR.zp2.cur[point].x += dx; 5452 exc->zp2.cur[point].x += dx;
5915 if ( touch ) 5453 if ( touch )
5916 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; 5454 exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
5917 } 5455 }
5918 5456
5919 if ( CUR.GS.freeVector.y != 0 ) 5457 if ( exc->GS.freeVector.y != 0 )
5920 { 5458 {
5921 CUR.zp2.cur[point].y += dy; 5459 exc->zp2.cur[point].y += dy;
5922 if ( touch ) 5460 if ( touch )
5923 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; 5461 exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
5924 } 5462 }
5925 } 5463 }
5926 5464
5927 5465
5928 /*************************************************************************/ 5466 /*************************************************************************/
5929 /* */ 5467 /* */
5930 /* SHP[a]: SHift Point by the last point */ 5468 /* SHP[a]: SHift Point by the last point */
5931 /* Opcode range: 0x32-0x33 */ 5469 /* Opcode range: 0x32-0x33 */
5932 /* Stack: uint32... --> */ 5470 /* Stack: uint32... --> */
5933 /* */ 5471 /* */
5934 static void 5472 static void
5935 Ins_SHP( INS_ARG ) 5473 Ins_SHP( TT_ExecContext exc )
5936 { 5474 {
5937 TT_GlyphZoneRec zp; 5475 TT_GlyphZoneRec zp;
5938 FT_UShort refp; 5476 FT_UShort refp;
5939 5477
5940 FT_F26Dot6 dx, 5478 FT_F26Dot6 dx, dy;
5941 dy;
5942 FT_UShort point; 5479 FT_UShort point;
5943 5480
5944 FT_UNUSED_ARG;
5945 5481
5946 5482 if ( exc->top < exc->GS.loop )
5947 if ( CUR.top < CUR.GS.loop )
5948 { 5483 {
5949 if ( CUR.pedantic_hinting ) 5484 if ( exc->pedantic_hinting )
5950 CUR.error = FT_THROW( Invalid_Reference ); 5485 exc->error = FT_THROW( Invalid_Reference );
5951 goto Fail; 5486 goto Fail;
5952 } 5487 }
5953 5488
5954 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5489 if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
5955 return; 5490 return;
5956 5491
5957 while ( CUR.GS.loop > 0 ) 5492 while ( exc->GS.loop > 0 )
5958 { 5493 {
5959 CUR.args--; 5494 exc->args--;
5960 point = (FT_UShort)CUR.stack[CUR.args]; 5495 point = (FT_UShort)exc->stack[exc->args];
5961 5496
5962 if ( BOUNDS( point, CUR.zp2.n_points ) ) 5497 if ( BOUNDS( point, exc->zp2.n_points ) )
5963 { 5498 {
5964 if ( CUR.pedantic_hinting ) 5499 if ( exc->pedantic_hinting )
5965 { 5500 {
5966 CUR.error = FT_THROW( Invalid_Reference ); 5501 exc->error = FT_THROW( Invalid_Reference );
5967 return; 5502 return;
5968 } 5503 }
5969 } 5504 }
5970 else 5505 else
5971 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5506 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
5972 /* doesn't follow Cleartype spec but produces better result */ 5507 /* doesn't follow Cleartype spec but produces better result */
5973 if ( SUBPIXEL_HINTING && 5508 if ( SUBPIXEL_HINTING &&
5974 CUR.ignore_x_mode ) 5509 exc->ignore_x_mode )
5975 MOVE_Zp2_Point( point, 0, dy, TRUE ); 5510 Move_Zp2_Point( exc, point, 0, dy, TRUE );
5976 else 5511 else
5977 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5512 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
5978 MOVE_Zp2_Point( point, dx, dy, TRUE ); 5513 Move_Zp2_Point( exc, point, dx, dy, TRUE );
5979 5514
5980 CUR.GS.loop--; 5515 exc->GS.loop--;
5981 } 5516 }
5982 5517
5983 Fail: 5518 Fail:
5984 CUR.GS.loop = 1; 5519 exc->GS.loop = 1;
5985 CUR.new_top = CUR.args; 5520 exc->new_top = exc->args;
5986 } 5521 }
5987 5522
5988 5523
5989 /*************************************************************************/ 5524 /*************************************************************************/
5990 /* */ 5525 /* */
5991 /* SHC[a]: SHift Contour */ 5526 /* SHC[a]: SHift Contour */
5992 /* Opcode range: 0x34-35 */ 5527 /* Opcode range: 0x34-35 */
5993 /* Stack: uint32 --> */ 5528 /* Stack: uint32 --> */
5994 /* */ 5529 /* */
5995 /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ 5530 /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */
5996 /* contour in the twilight zone, namely contour number */ 5531 /* contour in the twilight zone, namely contour number */
5997 /* zero which includes all points of it. */ 5532 /* zero which includes all points of it. */
5998 /* */ 5533 /* */
5999 static void 5534 static void
6000 Ins_SHC( INS_ARG ) 5535 Ins_SHC( TT_ExecContext exc,
5536 FT_Long* args )
6001 { 5537 {
6002 TT_GlyphZoneRec zp; 5538 TT_GlyphZoneRec zp;
6003 FT_UShort refp; 5539 FT_UShort refp;
6004 FT_F26Dot6 dx, dy; 5540 FT_F26Dot6 dx, dy;
6005 5541
6006 FT_Short contour, bounds; 5542 FT_Short contour, bounds;
6007 FT_UShort start, limit, i; 5543 FT_UShort start, limit, i;
6008 5544
6009 5545
6010 contour = (FT_UShort)args[0]; 5546 contour = (FT_Short)args[0];
6011 bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; 5547 bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
6012 5548
6013 if ( BOUNDS( contour, bounds ) ) 5549 if ( BOUNDS( contour, bounds ) )
6014 { 5550 {
6015 if ( CUR.pedantic_hinting ) 5551 if ( exc->pedantic_hinting )
6016 CUR.error = FT_THROW( Invalid_Reference ); 5552 exc->error = FT_THROW( Invalid_Reference );
6017 return; 5553 return;
6018 } 5554 }
6019 5555
6020 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5556 if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
6021 return; 5557 return;
6022 5558
6023 if ( contour == 0 ) 5559 if ( contour == 0 )
6024 start = 0; 5560 start = 0;
6025 else 5561 else
6026 start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - 5562 start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
6027 CUR.zp2.first_point ); 5563 exc->zp2.first_point );
6028 5564
6029 /* we use the number of points if in the twilight zone */ 5565 /* we use the number of points if in the twilight zone */
6030 if ( CUR.GS.gep2 == 0 ) 5566 if ( exc->GS.gep2 == 0 )
6031 limit = CUR.zp2.n_points; 5567 limit = exc->zp2.n_points;
6032 else 5568 else
6033 limit = (FT_UShort)( CUR.zp2.contours[contour] - 5569 limit = (FT_UShort)( exc->zp2.contours[contour] -
6034 CUR.zp2.first_point + 1 ); 5570 exc->zp2.first_point + 1 );
6035 5571
6036 for ( i = start; i < limit; i++ ) 5572 for ( i = start; i < limit; i++ )
6037 { 5573 {
6038 if ( zp.cur != CUR.zp2.cur || refp != i ) 5574 if ( zp.cur != exc->zp2.cur || refp != i )
6039 MOVE_Zp2_Point( i, dx, dy, TRUE ); 5575 Move_Zp2_Point( exc, i, dx, dy, TRUE );
6040 } 5576 }
6041 } 5577 }
6042 5578
6043 5579
6044 /*************************************************************************/ 5580 /*************************************************************************/
6045 /* */ 5581 /* */
6046 /* SHZ[a]: SHift Zone */ 5582 /* SHZ[a]: SHift Zone */
6047 /* Opcode range: 0x36-37 */ 5583 /* Opcode range: 0x36-37 */
6048 /* Stack: uint32 --> */ 5584 /* Stack: uint32 --> */
6049 /* */ 5585 /* */
6050 static void 5586 static void
6051 Ins_SHZ( INS_ARG ) 5587 Ins_SHZ( TT_ExecContext exc,
5588 FT_Long* args )
6052 { 5589 {
6053 TT_GlyphZoneRec zp; 5590 TT_GlyphZoneRec zp;
6054 FT_UShort refp; 5591 FT_UShort refp;
6055 FT_F26Dot6 dx, 5592 FT_F26Dot6 dx,
6056 dy; 5593 dy;
6057 5594
6058 FT_UShort limit, i; 5595 FT_UShort limit, i;
6059 5596
6060 5597
6061 if ( BOUNDS( args[0], 2 ) ) 5598 if ( BOUNDS( args[0], 2 ) )
6062 { 5599 {
6063 if ( CUR.pedantic_hinting ) 5600 if ( exc->pedantic_hinting )
6064 CUR.error = FT_THROW( Invalid_Reference ); 5601 exc->error = FT_THROW( Invalid_Reference );
6065 return; 5602 return;
6066 } 5603 }
6067 5604
6068 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5605 if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
6069 return; 5606 return;
6070 5607
6071 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ 5608 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
6072 /* Twilight zone has no real contours, so use `n_points'. */ 5609 /* Twilight zone has no real contours, so use `n_points'. */
6073 /* Normal zone's `n_points' includes phantoms, so must */ 5610 /* Normal zone's `n_points' includes phantoms, so must */
6074 /* use end of last contour. */ 5611 /* use end of last contour. */
6075 if ( CUR.GS.gep2 == 0 ) 5612 if ( exc->GS.gep2 == 0 )
6076 limit = (FT_UShort)CUR.zp2.n_points; 5613 limit = (FT_UShort)exc->zp2.n_points;
6077 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) 5614 else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
6078 limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); 5615 limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
6079 else 5616 else
6080 limit = 0; 5617 limit = 0;
6081 5618
6082 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ 5619 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
6083 for ( i = 0; i < limit; i++ ) 5620 for ( i = 0; i < limit; i++ )
6084 { 5621 {
6085 if ( zp.cur != CUR.zp2.cur || refp != i ) 5622 if ( zp.cur != exc->zp2.cur || refp != i )
6086 MOVE_Zp2_Point( i, dx, dy, FALSE ); 5623 Move_Zp2_Point( exc, i, dx, dy, FALSE );
6087 } 5624 }
6088 } 5625 }
6089 5626
6090 5627
6091 /*************************************************************************/ 5628 /*************************************************************************/
6092 /* */ 5629 /* */
6093 /* SHPIX[]: SHift points by a PIXel amount */ 5630 /* SHPIX[]: SHift points by a PIXel amount */
6094 /* Opcode range: 0x38 */ 5631 /* Opcode range: 0x38 */
6095 /* Stack: f26.6 uint32... --> */ 5632 /* Stack: f26.6 uint32... --> */
6096 /* */ 5633 /* */
6097 static void 5634 static void
6098 Ins_SHPIX( INS_ARG ) 5635 Ins_SHPIX( TT_ExecContext exc,
5636 FT_Long* args )
6099 { 5637 {
6100 FT_F26Dot6 dx, dy; 5638 FT_F26Dot6 dx, dy;
6101 FT_UShort point; 5639 FT_UShort point;
6102 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5640 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6103 FT_Int B1, B2; 5641 FT_Int B1, B2;
6104 #endif 5642 #endif
6105 5643
6106 5644
6107 if ( CUR.top < CUR.GS.loop + 1 ) 5645 if ( exc->top < exc->GS.loop + 1 )
6108 { 5646 {
6109 if ( CUR.pedantic_hinting ) 5647 if ( exc->pedantic_hinting )
6110 CUR.error = FT_THROW( Invalid_Reference ); 5648 exc->error = FT_THROW( Invalid_Reference );
6111 goto Fail; 5649 goto Fail;
6112 } 5650 }
6113 5651
6114 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 5652 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
6115 if ( CUR.face->unpatented_hinting ) 5653 if ( exc->face->unpatented_hinting )
6116 { 5654 {
6117 if ( CUR.GS.both_x_axis ) 5655 if ( exc->GS.both_x_axis )
6118 { 5656 {
6119 dx = (FT_UInt32)args[0]; 5657 dx = (FT_UInt32)args[0];
6120 dy = 0; 5658 dy = 0;
6121 } 5659 }
6122 else 5660 else
6123 { 5661 {
6124 dx = 0; 5662 dx = 0;
6125 dy = (FT_UInt32)args[0]; 5663 dy = (FT_UInt32)args[0];
6126 } 5664 }
6127 } 5665 }
6128 else 5666 else
6129 #endif 5667 #endif
6130 { 5668 {
6131 dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); 5669 dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
6132 dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); 5670 dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
6133 } 5671 }
6134 5672
6135 while ( CUR.GS.loop > 0 ) 5673 while ( exc->GS.loop > 0 )
6136 { 5674 {
6137 CUR.args--; 5675 exc->args--;
6138 5676
6139 point = (FT_UShort)CUR.stack[CUR.args]; 5677 point = (FT_UShort)exc->stack[exc->args];
6140 5678
6141 if ( BOUNDS( point, CUR.zp2.n_points ) ) 5679 if ( BOUNDS( point, exc->zp2.n_points ) )
6142 { 5680 {
6143 if ( CUR.pedantic_hinting ) 5681 if ( exc->pedantic_hinting )
6144 { 5682 {
6145 CUR.error = FT_THROW( Invalid_Reference ); 5683 exc->error = FT_THROW( Invalid_Reference );
6146 return; 5684 return;
6147 } 5685 }
6148 } 5686 }
6149 else 5687 else
6150 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5688 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6151 { 5689 {
6152 /* If not using ignore_x_mode rendering, allow ZP2 move. */ 5690 /* If not using ignore_x_mode rendering, allow ZP2 move. */
6153 /* If inline deltas aren't allowed, skip ZP2 move. */ 5691 /* If inline deltas aren't allowed, skip ZP2 move. */
6154 /* If using ignore_x_mode rendering, allow ZP2 point move if: */ 5692 /* If using ignore_x_mode rendering, allow ZP2 point move if: */
6155 /* - freedom vector is y and sph_compatibility_mode is off */ 5693 /* - freedom vector is y and sph_compatibility_mode is off */
6156 /* - the glyph is composite and the move is in the Y direction */ 5694 /* - the glyph is composite and the move is in the Y direction */
6157 /* - the glyph is specifically set to allow SHPIX moves */ 5695 /* - the glyph is specifically set to allow SHPIX moves */
6158 /* - the move is on a previously Y-touched point */ 5696 /* - the move is on a previously Y-touched point */
6159 5697
6160 if ( SUBPIXEL_HINTING && 5698 if ( SUBPIXEL_HINTING &&
6161 CUR.ignore_x_mode ) 5699 exc->ignore_x_mode )
6162 { 5700 {
6163 /* save point for later comparison */ 5701 /* save point for later comparison */
6164 if ( CUR.GS.freeVector.y != 0 ) 5702 if ( exc->GS.freeVector.y != 0 )
6165 B1 = CUR.zp2.cur[point].y; 5703 B1 = exc->zp2.cur[point].y;
6166 else 5704 else
6167 B1 = CUR.zp2.cur[point].x; 5705 B1 = exc->zp2.cur[point].x;
6168 5706
6169 if ( !CUR.face->sph_compatibility_mode && 5707 if ( !exc->face->sph_compatibility_mode &&
6170 CUR.GS.freeVector.y != 0 ) 5708 exc->GS.freeVector.y != 0 )
6171 { 5709 {
6172 MOVE_Zp2_Point( point, dx, dy, TRUE ); 5710 Move_Zp2_Point( exc, point, dx, dy, TRUE );
6173 5711
6174 /* save new point */ 5712 /* save new point */
6175 if ( CUR.GS.freeVector.y != 0 ) 5713 if ( exc->GS.freeVector.y != 0 )
6176 { 5714 {
6177 B2 = CUR.zp2.cur[point].y; 5715 B2 = exc->zp2.cur[point].y;
6178 5716
6179 /* reverse any disallowed moves */ 5717 /* reverse any disallowed moves */
6180 if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && 5718 if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
6181 ( B1 & 63 ) != 0 && 5719 ( B1 & 63 ) != 0 &&
6182 ( B2 & 63 ) != 0 && 5720 ( B2 & 63 ) != 0 &&
6183 B1 != B2 ) 5721 B1 != B2 )
6184 MOVE_Zp2_Point( point, -dx, -dy, TRUE ); 5722 Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
6185 } 5723 }
6186 } 5724 }
6187 else if ( CUR.face->sph_compatibility_mode ) 5725 else if ( exc->face->sph_compatibility_mode )
6188 { 5726 {
6189 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) 5727 if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
6190 { 5728 {
6191 dx = FT_PIX_ROUND( B1 + dx ) - B1; 5729 dx = FT_PIX_ROUND( B1 + dx ) - B1;
6192 dy = FT_PIX_ROUND( B1 + dy ) - B1; 5730 dy = FT_PIX_ROUND( B1 + dy ) - B1;
6193 } 5731 }
6194 5732
6195 /* skip post-iup deltas */ 5733 /* skip post-iup deltas */
6196 if ( CUR.iup_called && 5734 if ( exc->iup_called &&
6197 ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || 5735 ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
6198 ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) 5736 ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
6199 goto Skip; 5737 goto Skip;
6200 5738
6201 if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && 5739 if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
6202 ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || 5740 ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
6203 ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || 5741 ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
6204 ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) 5742 ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
6205 MOVE_Zp2_Point( point, 0, dy, TRUE ); 5743 Move_Zp2_Point( exc, point, 0, dy, TRUE );
6206 5744
6207 /* save new point */ 5745 /* save new point */
6208 if ( CUR.GS.freeVector.y != 0 ) 5746 if ( exc->GS.freeVector.y != 0 )
6209 { 5747 {
6210 B2 = CUR.zp2.cur[point].y; 5748 B2 = exc->zp2.cur[point].y;
6211 5749
6212 /* reverse any disallowed moves */ 5750 /* reverse any disallowed moves */
6213 if ( ( B1 & 63 ) == 0 && 5751 if ( ( B1 & 63 ) == 0 &&
6214 ( B2 & 63 ) != 0 && 5752 ( B2 & 63 ) != 0 &&
6215 B1 != B2 ) 5753 B1 != B2 )
6216 MOVE_Zp2_Point( point, 0, -dy, TRUE ); 5754 Move_Zp2_Point( exc, point, 0, -dy, TRUE );
6217 } 5755 }
6218 } 5756 }
6219 else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) 5757 else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
6220 MOVE_Zp2_Point( point, dx, dy, TRUE ); 5758 Move_Zp2_Point( exc, point, dx, dy, TRUE );
6221 } 5759 }
6222 else 5760 else
6223 MOVE_Zp2_Point( point, dx, dy, TRUE ); 5761 Move_Zp2_Point( exc, point, dx, dy, TRUE );
6224 } 5762 }
6225 5763
6226 Skip: 5764 Skip:
6227 5765
6228 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5766 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6229 5767
6230 MOVE_Zp2_Point( point, dx, dy, TRUE ); 5768 Move_Zp2_Point( exc, point, dx, dy, TRUE );
6231 5769
6232 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5770 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6233 5771
6234 CUR.GS.loop--; 5772 exc->GS.loop--;
6235 } 5773 }
6236 5774
6237 Fail: 5775 Fail:
6238 CUR.GS.loop = 1; 5776 exc->GS.loop = 1;
6239 CUR.new_top = CUR.args; 5777 exc->new_top = exc->args;
6240 } 5778 }
6241 5779
6242 5780
6243 /*************************************************************************/ 5781 /*************************************************************************/
6244 /* */ 5782 /* */
6245 /* MSIRP[a]: Move Stack Indirect Relative Position */ 5783 /* MSIRP[a]: Move Stack Indirect Relative Position */
6246 /* Opcode range: 0x3A-0x3B */ 5784 /* Opcode range: 0x3A-0x3B */
6247 /* Stack: f26.6 uint32 --> */ 5785 /* Stack: f26.6 uint32 --> */
6248 /* */ 5786 /* */
6249 static void 5787 static void
6250 Ins_MSIRP( INS_ARG ) 5788 Ins_MSIRP( TT_ExecContext exc,
5789 FT_Long* args )
6251 { 5790 {
6252 FT_UShort point; 5791 FT_UShort point;
6253 FT_F26Dot6 distance; 5792 FT_F26Dot6 distance;
6254 5793
6255 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5794 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6256 FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ 5795 FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */
6257 5796
6258 5797
6259 if ( SUBPIXEL_HINTING ) 5798 if ( SUBPIXEL_HINTING )
6260 { 5799 {
6261 control_value_cutin = CUR.GS.control_value_cutin; 5800 control_value_cutin = exc->GS.control_value_cutin;
6262 5801
6263 if ( CUR.ignore_x_mode && 5802 if ( exc->ignore_x_mode &&
6264 CUR.GS.freeVector.x != 0 && 5803 exc->GS.freeVector.x != 0 &&
6265 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) 5804 !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
6266 control_value_cutin = 0; 5805 control_value_cutin = 0;
6267 } 5806 }
6268 5807
6269 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5808 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6270 5809
6271 point = (FT_UShort)args[0]; 5810 point = (FT_UShort)args[0];
6272 5811
6273 if ( BOUNDS( point, CUR.zp1.n_points ) || 5812 if ( BOUNDS( point, exc->zp1.n_points ) ||
6274 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 5813 BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
6275 { 5814 {
6276 if ( CUR.pedantic_hinting ) 5815 if ( exc->pedantic_hinting )
6277 CUR.error = FT_THROW( Invalid_Reference ); 5816 exc->error = FT_THROW( Invalid_Reference );
6278 return; 5817 return;
6279 } 5818 }
6280 5819
6281 /* UNDOCUMENTED! The MS rasterizer does that with */ 5820 /* UNDOCUMENTED! The MS rasterizer does that with */
6282 /* twilight points (confirmed by Greg Hitchcock) */ 5821 /* twilight points (confirmed by Greg Hitchcock) */
6283 if ( CUR.GS.gep1 == 0 ) 5822 if ( exc->GS.gep1 == 0 )
6284 { 5823 {
6285 CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; 5824 exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
6286 CUR_Func_move_orig( &CUR.zp1, point, args[1] ); 5825 exc->func_move_orig( exc, &exc->zp1, point, args[1] );
6287 CUR.zp1.cur[point] = CUR.zp1.org[point]; 5826 exc->zp1.cur[point] = exc->zp1.org[point];
6288 } 5827 }
6289 5828
6290 distance = CUR_Func_project( CUR.zp1.cur + point, 5829 distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
6291 CUR.zp0.cur + CUR.GS.rp0 );
6292 5830
6293 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5831 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6294 /* subpixel hinting - make MSIRP respect CVT cut-in; */ 5832 /* subpixel hinting - make MSIRP respect CVT cut-in; */
6295 if ( SUBPIXEL_HINTING && 5833 if ( SUBPIXEL_HINTING &&
6296 CUR.ignore_x_mode && 5834 exc->ignore_x_mode &&
6297 CUR.GS.freeVector.x != 0 && 5835 exc->GS.freeVector.x != 0 &&
6298 FT_ABS( distance - args[1] ) >= control_value_cutin ) 5836 FT_ABS( distance - args[1] ) >= control_value_cutin )
6299 distance = args[1]; 5837 distance = args[1];
6300 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5838 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6301 5839
6302 CUR_Func_move( &CUR.zp1, point, args[1] - distance ); 5840 exc->func_move( exc, &exc->zp1, point, args[1] - distance );
6303 5841
6304 CUR.GS.rp1 = CUR.GS.rp0; 5842 exc->GS.rp1 = exc->GS.rp0;
6305 CUR.GS.rp2 = point; 5843 exc->GS.rp2 = point;
6306 5844
6307 if ( ( CUR.opcode & 1 ) != 0 ) 5845 if ( ( exc->opcode & 1 ) != 0 )
6308 CUR.GS.rp0 = point; 5846 exc->GS.rp0 = point;
6309 } 5847 }
6310 5848
6311 5849
6312 /*************************************************************************/ 5850 /*************************************************************************/
6313 /* */ 5851 /* */
6314 /* MDAP[a]: Move Direct Absolute Point */ 5852 /* MDAP[a]: Move Direct Absolute Point */
6315 /* Opcode range: 0x2E-0x2F */ 5853 /* Opcode range: 0x2E-0x2F */
6316 /* Stack: uint32 --> */ 5854 /* Stack: uint32 --> */
6317 /* */ 5855 /* */
6318 static void 5856 static void
6319 Ins_MDAP( INS_ARG ) 5857 Ins_MDAP( TT_ExecContext exc,
5858 FT_Long* args )
6320 { 5859 {
6321 FT_UShort point; 5860 FT_UShort point;
6322 FT_F26Dot6 cur_dist; 5861 FT_F26Dot6 cur_dist;
6323 FT_F26Dot6 distance; 5862 FT_F26Dot6 distance;
6324 5863
6325 5864
6326 point = (FT_UShort)args[0]; 5865 point = (FT_UShort)args[0];
6327 5866
6328 if ( BOUNDS( point, CUR.zp0.n_points ) ) 5867 if ( BOUNDS( point, exc->zp0.n_points ) )
6329 { 5868 {
6330 if ( CUR.pedantic_hinting ) 5869 if ( exc->pedantic_hinting )
6331 CUR.error = FT_THROW( Invalid_Reference ); 5870 exc->error = FT_THROW( Invalid_Reference );
6332 return; 5871 return;
6333 } 5872 }
6334 5873
6335 if ( ( CUR.opcode & 1 ) != 0 ) 5874 if ( ( exc->opcode & 1 ) != 0 )
6336 { 5875 {
6337 cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); 5876 cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
6338 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5877 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6339 if ( SUBPIXEL_HINTING && 5878 if ( SUBPIXEL_HINTING &&
6340 CUR.ignore_x_mode && 5879 exc->ignore_x_mode &&
6341 CUR.GS.freeVector.x != 0 ) 5880 exc->GS.freeVector.x != 0 )
6342 distance = ROUND_None( 5881 distance = Round_None(
5882 exc,
6343 cur_dist, 5883 cur_dist,
6344 CUR.tt_metrics.compensations[0] ) - cur_dist; 5884 exc->tt_metrics.compensations[0] ) - cur_dist;
6345 else 5885 else
6346 #endif 5886 #endif
6347 distance = CUR_Func_round( 5887 distance = exc->func_round(
5888 exc,
6348 cur_dist, 5889 cur_dist,
6349 CUR.tt_metrics.compensations[0] ) - cur_dist; 5890 exc->tt_metrics.compensations[0] ) - cur_dist;
6350 } 5891 }
6351 else 5892 else
6352 distance = 0; 5893 distance = 0;
6353 5894
6354 CUR_Func_move( &CUR.zp0, point, distance ); 5895 exc->func_move( exc, &exc->zp0, point, distance );
6355 5896
6356 CUR.GS.rp0 = point; 5897 exc->GS.rp0 = point;
6357 CUR.GS.rp1 = point; 5898 exc->GS.rp1 = point;
6358 } 5899 }
6359 5900
6360 5901
6361 /*************************************************************************/ 5902 /*************************************************************************/
6362 /* */ 5903 /* */
6363 /* MIAP[a]: Move Indirect Absolute Point */ 5904 /* MIAP[a]: Move Indirect Absolute Point */
6364 /* Opcode range: 0x3E-0x3F */ 5905 /* Opcode range: 0x3E-0x3F */
6365 /* Stack: uint32 uint32 --> */ 5906 /* Stack: uint32 uint32 --> */
6366 /* */ 5907 /* */
6367 static void 5908 static void
6368 Ins_MIAP( INS_ARG ) 5909 Ins_MIAP( TT_ExecContext exc,
5910 FT_Long* args )
6369 { 5911 {
6370 FT_ULong cvtEntry; 5912 FT_ULong cvtEntry;
6371 FT_UShort point; 5913 FT_UShort point;
6372 FT_F26Dot6 distance; 5914 FT_F26Dot6 distance;
6373 FT_F26Dot6 org_dist; 5915 FT_F26Dot6 org_dist;
6374 FT_F26Dot6 control_value_cutin; 5916 FT_F26Dot6 control_value_cutin;
6375 5917
6376 5918
6377 control_value_cutin = CUR.GS.control_value_cutin; 5919 control_value_cutin = exc->GS.control_value_cutin;
6378 cvtEntry = (FT_ULong)args[1]; 5920 cvtEntry = (FT_ULong)args[1];
6379 point = (FT_UShort)args[0]; 5921 point = (FT_UShort)args[0];
6380 5922
6381 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5923 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6382 if ( SUBPIXEL_HINTING && 5924 if ( SUBPIXEL_HINTING &&
6383 CUR.ignore_x_mode && 5925 exc->ignore_x_mode &&
6384 CUR.GS.freeVector.x != 0 && 5926 exc->GS.freeVector.x != 0 &&
6385 CUR.GS.freeVector.y == 0 && 5927 exc->GS.freeVector.y == 0 &&
6386 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) 5928 !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
6387 control_value_cutin = 0; 5929 control_value_cutin = 0;
6388 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5930 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6389 5931
6390 if ( BOUNDS( point, CUR.zp0.n_points ) || 5932 if ( BOUNDS( point, exc->zp0.n_points ) ||
6391 BOUNDSL( cvtEntry, CUR.cvtSize ) ) 5933 BOUNDSL( cvtEntry, exc->cvtSize ) )
6392 { 5934 {
6393 if ( CUR.pedantic_hinting ) 5935 if ( exc->pedantic_hinting )
6394 CUR.error = FT_THROW( Invalid_Reference ); 5936 exc->error = FT_THROW( Invalid_Reference );
6395 goto Fail; 5937 goto Fail;
6396 } 5938 }
6397 5939
6398 /* UNDOCUMENTED! */ 5940 /* UNDOCUMENTED! */
6399 /* */ 5941 /* */
6400 /* The behaviour of an MIAP instruction is quite different when used */ 5942 /* The behaviour of an MIAP instruction is quite different when used */
6401 /* in the twilight zone. */ 5943 /* in the twilight zone. */
6402 /* */ 5944 /* */
6403 /* First, no control value cut-in test is performed as it would fail */ 5945 /* First, no control value cut-in test is performed as it would fail */
6404 /* anyway. Second, the original point, i.e. (org_x,org_y) of */ 5946 /* anyway. Second, the original point, i.e. (org_x,org_y) of */
6405 /* zp0.point, is set to the absolute, unrounded distance found in the */ 5947 /* zp0.point, is set to the absolute, unrounded distance found in the */
6406 /* CVT. */ 5948 /* CVT. */
6407 /* */ 5949 /* */
6408 /* This is used in the CVT programs of the Microsoft fonts Arial, */ 5950 /* This is used in the CVT programs of the Microsoft fonts Arial, */
6409 /* Times, etc., in order to re-adjust some key font heights. It */ 5951 /* Times, etc., in order to re-adjust some key font heights. It */
6410 /* allows the use of the IP instruction in the twilight zone, which */ 5952 /* allows the use of the IP instruction in the twilight zone, which */
6411 /* otherwise would be invalid according to the specification. */ 5953 /* otherwise would be invalid according to the specification. */
6412 /* */ 5954 /* */
6413 /* We implement it with a special sequence for the twilight zone. */ 5955 /* We implement it with a special sequence for the twilight zone. */
6414 /* This is a bad hack, but it seems to work. */ 5956 /* This is a bad hack, but it seems to work. */
6415 /* */ 5957 /* */
6416 /* Confirmed by Greg Hitchcock. */ 5958 /* Confirmed by Greg Hitchcock. */
6417 5959
6418 distance = CUR_Func_read_cvt( cvtEntry ); 5960 distance = exc->func_read_cvt( exc, cvtEntry );
6419 5961
6420 if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ 5962 if ( exc->GS.gep0 == 0 ) /* If in twilight zone */
6421 { 5963 {
6422 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5964 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6423 /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ 5965 /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
6424 /* Determined via experimentation and may be incorrect... */ 5966 /* Determined via experimentation and may be incorrect... */
6425 if ( !SUBPIXEL_HINTING || 5967 if ( !SUBPIXEL_HINTING ||
6426 ( !CUR.ignore_x_mode || 5968 ( !exc->ignore_x_mode ||
6427 !CUR.face->sph_compatibility_mode ) ) 5969 !exc->face->sph_compatibility_mode ) )
6428 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5970 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6429 CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, 5971 exc->zp0.org[point].x = TT_MulFix14( distance,
6430 CUR.GS.freeVector.x ); 5972 exc->GS.freeVector.x );
6431 CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, 5973 exc->zp0.org[point].y = TT_MulFix14( distance,
6432 CUR.GS.freeVector.y ), 5974 exc->GS.freeVector.y ),
6433 CUR.zp0.cur[point] = CUR.zp0.org[point]; 5975 exc->zp0.cur[point] = exc->zp0.org[point];
6434 } 5976 }
6435 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5977 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6436 if ( SUBPIXEL_HINTING && 5978 if ( SUBPIXEL_HINTING &&
6437 CUR.ignore_x_mode && 5979 exc->ignore_x_mode &&
6438 ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && 5980 ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
6439 distance > 0 && 5981 distance > 0 &&
6440 CUR.GS.freeVector.y != 0 ) 5982 exc->GS.freeVector.y != 0 )
6441 distance = 0; 5983 distance = 0;
6442 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 5984 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6443 5985
6444 org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); 5986 org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
6445 5987
6446 if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ 5988 if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
6447 { 5989 {
6448 if ( FT_ABS( distance - org_dist ) > control_value_cutin ) 5990 if ( FT_ABS( distance - org_dist ) > control_value_cutin )
6449 distance = org_dist; 5991 distance = org_dist;
6450 5992
6451 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 5993 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6452 if ( SUBPIXEL_HINTING && 5994 if ( SUBPIXEL_HINTING &&
6453 CUR.ignore_x_mode && 5995 exc->ignore_x_mode &&
6454 CUR.GS.freeVector.x != 0 ) 5996 exc->GS.freeVector.x != 0 )
6455 distance = ROUND_None( distance, 5997 distance = Round_None( exc,
6456 CUR.tt_metrics.compensations[0] ); 5998 distance,
5999 exc->tt_metrics.compensations[0] );
6457 else 6000 else
6458 #endif 6001 #endif
6459 distance = CUR_Func_round( distance, 6002 distance = exc->func_round( exc,
6460 CUR.tt_metrics.compensations[0] ); 6003 distance,
6004 exc->tt_metrics.compensations[0] );
6461 } 6005 }
6462 6006
6463 CUR_Func_move( &CUR.zp0, point, distance - org_dist ); 6007 exc->func_move( exc, &exc->zp0, point, distance - org_dist );
6464 6008
6465 Fail: 6009 Fail:
6466 CUR.GS.rp0 = point; 6010 exc->GS.rp0 = point;
6467 CUR.GS.rp1 = point; 6011 exc->GS.rp1 = point;
6468 } 6012 }
6469 6013
6470 6014
6471 /*************************************************************************/ 6015 /*************************************************************************/
6472 /* */ 6016 /* */
6473 /* MDRP[abcde]: Move Direct Relative Point */ 6017 /* MDRP[abcde]: Move Direct Relative Point */
6474 /* Opcode range: 0xC0-0xDF */ 6018 /* Opcode range: 0xC0-0xDF */
6475 /* Stack: uint32 --> */ 6019 /* Stack: uint32 --> */
6476 /* */ 6020 /* */
6477 static void 6021 static void
6478 Ins_MDRP( INS_ARG ) 6022 Ins_MDRP( TT_ExecContext exc,
6023 FT_Long* args )
6479 { 6024 {
6480 FT_UShort point; 6025 FT_UShort point;
6481 FT_F26Dot6 org_dist, distance, minimum_distance; 6026 FT_F26Dot6 org_dist, distance, minimum_distance;
6482 6027
6483 6028
6484 minimum_distance = CUR.GS.minimum_distance; 6029 minimum_distance = exc->GS.minimum_distance;
6485 6030
6486 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6031 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6487 if ( SUBPIXEL_HINTING && 6032 if ( SUBPIXEL_HINTING &&
6488 CUR.ignore_x_mode && 6033 exc->ignore_x_mode &&
6489 CUR.GS.freeVector.x != 0 && 6034 exc->GS.freeVector.x != 0 &&
6490 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) 6035 !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
6491 minimum_distance = 0; 6036 minimum_distance = 0;
6492 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6037 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6493 6038
6494 point = (FT_UShort)args[0]; 6039 point = (FT_UShort)args[0];
6495 6040
6496 if ( BOUNDS( point, CUR.zp1.n_points ) || 6041 if ( BOUNDS( point, exc->zp1.n_points ) ||
6497 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 6042 BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
6498 { 6043 {
6499 if ( CUR.pedantic_hinting ) 6044 if ( exc->pedantic_hinting )
6500 CUR.error = FT_THROW( Invalid_Reference ); 6045 exc->error = FT_THROW( Invalid_Reference );
6501 goto Fail; 6046 goto Fail;
6502 } 6047 }
6503 6048
6504 /* XXX: Is there some undocumented feature while in the */ 6049 /* XXX: Is there some undocumented feature while in the */
6505 /* twilight zone? */ 6050 /* twilight zone? */
6506 6051
6507 /* XXX: UNDOCUMENTED: twilight zone special case */ 6052 /* XXX: UNDOCUMENTED: twilight zone special case */
6508 6053
6509 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) 6054 if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
6510 { 6055 {
6511 FT_Vector* vec1 = &CUR.zp1.org[point]; 6056 FT_Vector* vec1 = &exc->zp1.org[point];
6512 FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; 6057 FT_Vector* vec2 = &exc->zp0.org[exc->GS.rp0];
6513 6058
6514 6059
6515 org_dist = CUR_Func_dualproj( vec1, vec2 ); 6060 org_dist = DUALPROJ( vec1, vec2 );
6516 } 6061 }
6517 else 6062 else
6518 { 6063 {
6519 FT_Vector* vec1 = &CUR.zp1.orus[point]; 6064 FT_Vector* vec1 = &exc->zp1.orus[point];
6520 FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; 6065 FT_Vector* vec2 = &exc->zp0.orus[exc->GS.rp0];
6521 6066
6522 6067
6523 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) 6068 if ( exc->metrics.x_scale == exc->metrics.y_scale )
6524 { 6069 {
6525 /* this should be faster */ 6070 /* this should be faster */
6526 org_dist = CUR_Func_dualproj( vec1, vec2 ); 6071 org_dist = DUALPROJ( vec1, vec2 );
6527 org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); 6072 org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
6528 } 6073 }
6529 else 6074 else
6530 { 6075 {
6531 FT_Vector vec; 6076 FT_Vector vec;
6532 6077
6533 6078
6534 vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); 6079 vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
6535 vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); 6080 vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
6536 6081
6537 org_dist = CUR_fast_dualproj( &vec ); 6082 org_dist = FAST_DUALPROJ( &vec );
6538 } 6083 }
6539 } 6084 }
6540 6085
6541 /* single width cut-in test */ 6086 /* single width cut-in test */
6542 6087
6543 if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < 6088 if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
6544 CUR.GS.single_width_cutin ) 6089 exc->GS.single_width_cutin )
6545 { 6090 {
6546 if ( org_dist >= 0 ) 6091 if ( org_dist >= 0 )
6547 org_dist = CUR.GS.single_width_value; 6092 org_dist = exc->GS.single_width_value;
6548 else 6093 else
6549 org_dist = -CUR.GS.single_width_value; 6094 org_dist = -exc->GS.single_width_value;
6550 } 6095 }
6551 6096
6552 /* round flag */ 6097 /* round flag */
6553 6098
6554 if ( ( CUR.opcode & 4 ) != 0 ) 6099 if ( ( exc->opcode & 4 ) != 0 )
6555 { 6100 {
6556 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6101 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6557 if ( SUBPIXEL_HINTING && 6102 if ( SUBPIXEL_HINTING &&
6558 CUR.ignore_x_mode && 6103 exc->ignore_x_mode &&
6559 CUR.GS.freeVector.x != 0 ) 6104 exc->GS.freeVector.x != 0 )
6560 distance = ROUND_None( 6105 distance = Round_None(
6106 exc,
6561 org_dist, 6107 org_dist,
6562 CUR.tt_metrics.compensations[CUR.opcode & 3] ); 6108 exc->tt_metrics.compensations[exc->opcode & 3] );
6563 else 6109 else
6564 #endif 6110 #endif
6565 distance = CUR_Func_round( 6111 distance = exc->func_round(
6566 org_dist, 6112 exc,
6567 CUR.tt_metrics.compensations[CUR.opcode & 3] ); 6113 org_dist,
6114 exc->tt_metrics.compensations[exc->opcode & 3] );
6568 } 6115 }
6569 else 6116 else
6570 distance = ROUND_None( 6117 distance = Round_None(
6118 exc,
6571 org_dist, 6119 org_dist,
6572 CUR.tt_metrics.compensations[CUR.opcode & 3] ); 6120 exc->tt_metrics.compensations[exc->opcode & 3] );
6573 6121
6574 /* minimum distance flag */ 6122 /* minimum distance flag */
6575 6123
6576 if ( ( CUR.opcode & 8 ) != 0 ) 6124 if ( ( exc->opcode & 8 ) != 0 )
6577 { 6125 {
6578 if ( org_dist >= 0 ) 6126 if ( org_dist >= 0 )
6579 { 6127 {
6580 if ( distance < minimum_distance ) 6128 if ( distance < minimum_distance )
6581 distance = minimum_distance; 6129 distance = minimum_distance;
6582 } 6130 }
6583 else 6131 else
6584 { 6132 {
6585 if ( distance > -minimum_distance ) 6133 if ( distance > -minimum_distance )
6586 distance = -minimum_distance; 6134 distance = -minimum_distance;
6587 } 6135 }
6588 } 6136 }
6589 6137
6590 /* now move the point */ 6138 /* now move the point */
6591 6139
6592 org_dist = CUR_Func_project( CUR.zp1.cur + point, 6140 org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
6593 CUR.zp0.cur + CUR.GS.rp0 );
6594 6141
6595 CUR_Func_move( &CUR.zp1, point, distance - org_dist ); 6142 exc->func_move( exc, &exc->zp1, point, distance - org_dist );
6596 6143
6597 Fail: 6144 Fail:
6598 CUR.GS.rp1 = CUR.GS.rp0; 6145 exc->GS.rp1 = exc->GS.rp0;
6599 CUR.GS.rp2 = point; 6146 exc->GS.rp2 = point;
6600 6147
6601 if ( ( CUR.opcode & 16 ) != 0 ) 6148 if ( ( exc->opcode & 16 ) != 0 )
6602 CUR.GS.rp0 = point; 6149 exc->GS.rp0 = point;
6603 } 6150 }
6604 6151
6605 6152
6606 /*************************************************************************/ 6153 /*************************************************************************/
6607 /* */ 6154 /* */
6608 /* MIRP[abcde]: Move Indirect Relative Point */ 6155 /* MIRP[abcde]: Move Indirect Relative Point */
6609 /* Opcode range: 0xE0-0xFF */ 6156 /* Opcode range: 0xE0-0xFF */
6610 /* Stack: int32? uint32 --> */ 6157 /* Stack: int32? uint32 --> */
6611 /* */ 6158 /* */
6612 static void 6159 static void
6613 Ins_MIRP( INS_ARG ) 6160 Ins_MIRP( TT_ExecContext exc,
6161 FT_Long* args )
6614 { 6162 {
6615 FT_UShort point; 6163 FT_UShort point;
6616 FT_ULong cvtEntry; 6164 FT_ULong cvtEntry;
6617 6165
6618 FT_F26Dot6 cvt_dist, 6166 FT_F26Dot6 cvt_dist,
6619 distance, 6167 distance,
6620 cur_dist, 6168 cur_dist,
6621 org_dist, 6169 org_dist,
6622 control_value_cutin, 6170 control_value_cutin,
6623 minimum_distance; 6171 minimum_distance;
6624 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6172 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6625 FT_Int B1 = 0; /* pacify compiler */ 6173 FT_Int B1 = 0; /* pacify compiler */
6626 FT_Int B2 = 0; 6174 FT_Int B2 = 0;
6627 FT_Bool reverse_move = FALSE; 6175 FT_Bool reverse_move = FALSE;
6628 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6176 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6629 6177
6630 6178
6631 minimum_distance = CUR.GS.minimum_distance; 6179 minimum_distance = exc->GS.minimum_distance;
6632 control_value_cutin = CUR.GS.control_value_cutin; 6180 control_value_cutin = exc->GS.control_value_cutin;
6633 point = (FT_UShort)args[0]; 6181 point = (FT_UShort)args[0];
6634 cvtEntry = (FT_ULong)( args[1] + 1 ); 6182 cvtEntry = (FT_ULong)( args[1] + 1 );
6635 6183
6636 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6184 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6637 if ( SUBPIXEL_HINTING && 6185 if ( SUBPIXEL_HINTING &&
6638 CUR.ignore_x_mode && 6186 exc->ignore_x_mode &&
6639 CUR.GS.freeVector.x != 0 && 6187 exc->GS.freeVector.x != 0 &&
6640 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) 6188 !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
6641 control_value_cutin = minimum_distance = 0; 6189 control_value_cutin = minimum_distance = 0;
6642 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6190 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6643 6191
6644 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ 6192 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
6645 6193
6646 if ( BOUNDS( point, CUR.zp1.n_points ) || 6194 if ( BOUNDS( point, exc->zp1.n_points ) ||
6647 BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || 6195 BOUNDSL( cvtEntry, exc->cvtSize + 1 ) ||
6648 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 6196 BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
6649 { 6197 {
6650 if ( CUR.pedantic_hinting ) 6198 if ( exc->pedantic_hinting )
6651 CUR.error = FT_THROW( Invalid_Reference ); 6199 exc->error = FT_THROW( Invalid_Reference );
6652 goto Fail; 6200 goto Fail;
6653 } 6201 }
6654 6202
6655 if ( !cvtEntry ) 6203 if ( !cvtEntry )
6656 cvt_dist = 0; 6204 cvt_dist = 0;
6657 else 6205 else
6658 cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); 6206 cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
6659 6207
6660 /* single width test */ 6208 /* single width test */
6661 6209
6662 if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < 6210 if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
6663 CUR.GS.single_width_cutin ) 6211 exc->GS.single_width_cutin )
6664 { 6212 {
6665 if ( cvt_dist >= 0 ) 6213 if ( cvt_dist >= 0 )
6666 cvt_dist = CUR.GS.single_width_value; 6214 cvt_dist = exc->GS.single_width_value;
6667 else 6215 else
6668 cvt_dist = -CUR.GS.single_width_value; 6216 cvt_dist = -exc->GS.single_width_value;
6669 } 6217 }
6670 6218
6671 /* UNDOCUMENTED! The MS rasterizer does that with */ 6219 /* UNDOCUMENTED! The MS rasterizer does that with */
6672 /* twilight points (confirmed by Greg Hitchcock) */ 6220 /* twilight points (confirmed by Greg Hitchcock) */
6673 if ( CUR.GS.gep1 == 0 ) 6221 if ( exc->GS.gep1 == 0 )
6674 { 6222 {
6675 CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + 6223 exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
6676 TT_MulFix14( (FT_UInt32)cvt_dist, 6224 TT_MulFix14( cvt_dist,
6677 CUR.GS.freeVector.x ); 6225 exc->GS.freeVector.x );
6678 CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + 6226 exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
6679 TT_MulFix14( (FT_UInt32)cvt_dist, 6227 TT_MulFix14( cvt_dist,
6680 CUR.GS.freeVector.y ); 6228 exc->GS.freeVector.y );
6681 CUR.zp1.cur[point] = CUR.zp1.org[point]; 6229 exc->zp1.cur[point] = exc->zp1.org[point];
6682 } 6230 }
6683 6231
6684 org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], 6232 org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
6685 &CUR.zp0.org[CUR.GS.rp0] ); 6233 cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
6686 cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
6687 &CUR.zp0.cur[CUR.GS.rp0] );
6688 6234
6689 /* auto-flip test */ 6235 /* auto-flip test */
6690 6236
6691 if ( CUR.GS.auto_flip ) 6237 if ( exc->GS.auto_flip )
6692 { 6238 {
6693 if ( ( org_dist ^ cvt_dist ) < 0 ) 6239 if ( ( org_dist ^ cvt_dist ) < 0 )
6694 cvt_dist = -cvt_dist; 6240 cvt_dist = -cvt_dist;
6695 } 6241 }
6696 6242
6697 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6243 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6698 if ( SUBPIXEL_HINTING && 6244 if ( SUBPIXEL_HINTING &&
6699 CUR.ignore_x_mode && 6245 exc->ignore_x_mode &&
6700 CUR.GS.freeVector.y != 0 && 6246 exc->GS.freeVector.y != 0 &&
6701 ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) 6247 ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
6702 { 6248 {
6703 if ( cur_dist < -64 ) 6249 if ( cur_dist < -64 )
6704 cvt_dist -= 16; 6250 cvt_dist -= 16;
6705 else if ( cur_dist > 64 && cur_dist < 84 ) 6251 else if ( cur_dist > 64 && cur_dist < 84 )
6706 cvt_dist += 32; 6252 cvt_dist += 32;
6707 } 6253 }
6708 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6254 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6709 6255
6710 /* control value cut-in and round */ 6256 /* control value cut-in and round */
6711 6257
6712 if ( ( CUR.opcode & 4 ) != 0 ) 6258 if ( ( exc->opcode & 4 ) != 0 )
6713 { 6259 {
6714 /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ 6260 /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */
6715 /* refer to the same zone. */ 6261 /* refer to the same zone. */
6716 6262
6717 if ( CUR.GS.gep0 == CUR.GS.gep1 ) 6263 if ( exc->GS.gep0 == exc->GS.gep1 )
6718 { 6264 {
6719 /* XXX: According to Greg Hitchcock, the following wording is */ 6265 /* XXX: According to Greg Hitchcock, the following wording is */
6720 /* the right one: */ 6266 /* the right one: */
6721 /* */ 6267 /* */
6722 /* When the absolute difference between the value in */ 6268 /* When the absolute difference between the value in */
6723 /* the table [CVT] and the measurement directly from */ 6269 /* the table [CVT] and the measurement directly from */
6724 /* the outline is _greater_ than the cut_in value, the */ 6270 /* the outline is _greater_ than the cut_in value, the */
6725 /* outline measurement is used. */ 6271 /* outline measurement is used. */
6726 /* */ 6272 /* */
6727 /* This is from `instgly.doc'. The description in */ 6273 /* This is from `instgly.doc'. The description in */
6728 /* `ttinst2.doc', version 1.66, is thus incorrect since */ 6274 /* `ttinst2.doc', version 1.66, is thus incorrect since */
6729 /* it implies `>=' instead of `>'. */ 6275 /* it implies `>=' instead of `>'. */
6730 6276
6731 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) 6277 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
6732 cvt_dist = org_dist; 6278 cvt_dist = org_dist;
6733 } 6279 }
6734 6280
6735 distance = CUR_Func_round( 6281 distance = exc->func_round(
6282 exc,
6736 cvt_dist, 6283 cvt_dist,
6737 CUR.tt_metrics.compensations[CUR.opcode & 3] ); 6284 exc->tt_metrics.compensations[exc->opcode & 3] );
6738 } 6285 }
6739 else 6286 else
6740 { 6287 {
6741 6288
6742 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6289 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6743 /* do cvt cut-in always in MIRP for sph */ 6290 /* do cvt cut-in always in MIRP for sph */
6744 if ( SUBPIXEL_HINTING && 6291 if ( SUBPIXEL_HINTING &&
6745 CUR.ignore_x_mode && 6292 exc->ignore_x_mode &&
6746 CUR.GS.gep0 == CUR.GS.gep1 ) 6293 exc->GS.gep0 == exc->GS.gep1 )
6747 { 6294 {
6748 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) 6295 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
6749 cvt_dist = org_dist; 6296 cvt_dist = org_dist;
6750 } 6297 }
6751 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6298 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6752 6299
6753 distance = ROUND_None( 6300 distance = Round_None(
6301 exc,
6754 cvt_dist, 6302 cvt_dist,
6755 CUR.tt_metrics.compensations[CUR.opcode & 3] ); 6303 exc->tt_metrics.compensations[exc->opcode & 3] );
6756 } 6304 }
6757 6305
6758 /* minimum distance test */ 6306 /* minimum distance test */
6759 6307
6760 if ( ( CUR.opcode & 8 ) != 0 ) 6308 if ( ( exc->opcode & 8 ) != 0 )
6761 { 6309 {
6762 if ( org_dist >= 0 ) 6310 if ( org_dist >= 0 )
6763 { 6311 {
6764 if ( distance < minimum_distance ) 6312 if ( distance < minimum_distance )
6765 distance = minimum_distance; 6313 distance = minimum_distance;
6766 } 6314 }
6767 else 6315 else
6768 { 6316 {
6769 if ( distance > -minimum_distance ) 6317 if ( distance > -minimum_distance )
6770 distance = -minimum_distance; 6318 distance = -minimum_distance;
6771 } 6319 }
6772 } 6320 }
6773 6321
6774 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6322 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6775 if ( SUBPIXEL_HINTING ) 6323 if ( SUBPIXEL_HINTING )
6776 { 6324 {
6777 B1 = CUR.zp1.cur[point].y; 6325 B1 = exc->zp1.cur[point].y;
6778 6326
6779 /* Round moves if necessary */ 6327 /* Round moves if necessary */
6780 if ( CUR.ignore_x_mode && 6328 if ( exc->ignore_x_mode &&
6781 CUR.GS.freeVector.y != 0 && 6329 exc->GS.freeVector.y != 0 &&
6782 ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) 6330 ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
6783 distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; 6331 distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
6784 6332
6785 if ( CUR.ignore_x_mode && 6333 if ( exc->ignore_x_mode &&
6786 CUR.GS.freeVector.y != 0 && 6334 exc->GS.freeVector.y != 0 &&
6787 ( CUR.opcode & 16 ) == 0 && 6335 ( exc->opcode & 16 ) == 0 &&
6788 ( CUR.opcode & 8 ) == 0 && 6336 ( exc->opcode & 8 ) == 0 &&
6789 ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) 6337 ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
6790 distance += 64; 6338 distance += 64;
6791 } 6339 }
6792 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6340 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6793 6341
6794 CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); 6342 exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
6795 6343
6796 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6344 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6797 if ( SUBPIXEL_HINTING ) 6345 if ( SUBPIXEL_HINTING )
6798 { 6346 {
6799 B2 = CUR.zp1.cur[point].y; 6347 B2 = exc->zp1.cur[point].y;
6800 6348
6801 /* Reverse move if necessary */ 6349 /* Reverse move if necessary */
6802 if ( CUR.ignore_x_mode ) 6350 if ( exc->ignore_x_mode )
6803 { 6351 {
6804 if ( CUR.face->sph_compatibility_mode && 6352 if ( exc->face->sph_compatibility_mode &&
6805 CUR.GS.freeVector.y != 0 && 6353 exc->GS.freeVector.y != 0 &&
6806 ( B1 & 63 ) == 0 && 6354 ( B1 & 63 ) == 0 &&
6807 ( B2 & 63 ) != 0 ) 6355 ( B2 & 63 ) != 0 )
6808 reverse_move = TRUE; 6356 reverse_move = TRUE;
6809 6357
6810 if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && 6358 if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
6811 CUR.GS.freeVector.y != 0 && 6359 exc->GS.freeVector.y != 0 &&
6812 ( B2 & 63 ) != 0 && 6360 ( B2 & 63 ) != 0 &&
6813 ( B1 & 63 ) != 0 ) 6361 ( B1 & 63 ) != 0 )
6814 reverse_move = TRUE; 6362 reverse_move = TRUE;
6815 } 6363 }
6816 6364
6817 if ( reverse_move ) 6365 if ( reverse_move )
6818 CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); 6366 exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
6819 } 6367 }
6820 6368
6821 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6369 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6822 6370
6823 Fail: 6371 Fail:
6824 CUR.GS.rp1 = CUR.GS.rp0; 6372 exc->GS.rp1 = exc->GS.rp0;
6825 6373
6826 if ( ( CUR.opcode & 16 ) != 0 ) 6374 if ( ( exc->opcode & 16 ) != 0 )
6827 CUR.GS.rp0 = point; 6375 exc->GS.rp0 = point;
6828 6376
6829 CUR.GS.rp2 = point; 6377 exc->GS.rp2 = point;
6830 } 6378 }
6831 6379
6832 6380
6833 /*************************************************************************/ 6381 /*************************************************************************/
6834 /* */ 6382 /* */
6835 /* ALIGNRP[]: ALIGN Relative Point */ 6383 /* ALIGNRP[]: ALIGN Relative Point */
6836 /* Opcode range: 0x3C */ 6384 /* Opcode range: 0x3C */
6837 /* Stack: uint32 uint32... --> */ 6385 /* Stack: uint32 uint32... --> */
6838 /* */ 6386 /* */
6839 static void 6387 static void
6840 Ins_ALIGNRP( INS_ARG ) 6388 Ins_ALIGNRP( TT_ExecContext exc )
6841 { 6389 {
6842 FT_UShort point; 6390 FT_UShort point;
6843 FT_F26Dot6 distance; 6391 FT_F26Dot6 distance;
6844 6392
6845 FT_UNUSED_ARG;
6846
6847 6393
6848 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6394 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6849 if ( SUBPIXEL_HINTING && 6395 if ( SUBPIXEL_HINTING &&
6850 CUR.ignore_x_mode && 6396 exc->ignore_x_mode &&
6851 CUR.iup_called && 6397 exc->iup_called &&
6852 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) 6398 ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
6853 { 6399 {
6854 CUR.error = FT_THROW( Invalid_Reference ); 6400 exc->error = FT_THROW( Invalid_Reference );
6855 goto Fail; 6401 goto Fail;
6856 } 6402 }
6857 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6403 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6858 6404
6859 if ( CUR.top < CUR.GS.loop || 6405 if ( exc->top < exc->GS.loop ||
6860 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 6406 BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
6861 { 6407 {
6862 if ( CUR.pedantic_hinting ) 6408 if ( exc->pedantic_hinting )
6863 CUR.error = FT_THROW( Invalid_Reference ); 6409 exc->error = FT_THROW( Invalid_Reference );
6864 goto Fail; 6410 goto Fail;
6865 } 6411 }
6866 6412
6867 while ( CUR.GS.loop > 0 ) 6413 while ( exc->GS.loop > 0 )
6868 { 6414 {
6869 CUR.args--; 6415 exc->args--;
6870 6416
6871 point = (FT_UShort)CUR.stack[CUR.args]; 6417 point = (FT_UShort)exc->stack[exc->args];
6872 6418
6873 if ( BOUNDS( point, CUR.zp1.n_points ) ) 6419 if ( BOUNDS( point, exc->zp1.n_points ) )
6874 { 6420 {
6875 if ( CUR.pedantic_hinting ) 6421 if ( exc->pedantic_hinting )
6876 { 6422 {
6877 CUR.error = FT_THROW( Invalid_Reference ); 6423 exc->error = FT_THROW( Invalid_Reference );
6878 return; 6424 return;
6879 } 6425 }
6880 } 6426 }
6881 else 6427 else
6882 { 6428 {
6883 distance = CUR_Func_project( CUR.zp1.cur + point, 6429 distance = PROJECT( exc->zp1.cur + point,
6884 CUR.zp0.cur + CUR.GS.rp0 ); 6430 exc->zp0.cur + exc->GS.rp0 );
6885 6431
6886 CUR_Func_move( &CUR.zp1, point, -distance ); 6432 exc->func_move( exc, &exc->zp1, point, -distance );
6887 } 6433 }
6888 6434
6889 CUR.GS.loop--; 6435 exc->GS.loop--;
6890 } 6436 }
6891 6437
6892 Fail: 6438 Fail:
6893 CUR.GS.loop = 1; 6439 exc->GS.loop = 1;
6894 CUR.new_top = CUR.args; 6440 exc->new_top = exc->args;
6895 } 6441 }
6896 6442
6897 6443
6898 /*************************************************************************/ 6444 /*************************************************************************/
6899 /* */ 6445 /* */
6900 /* ISECT[]: moves point to InterSECTion */ 6446 /* ISECT[]: moves point to InterSECTion */
6901 /* Opcode range: 0x0F */ 6447 /* Opcode range: 0x0F */
6902 /* Stack: 5 * uint32 --> */ 6448 /* Stack: 5 * uint32 --> */
6903 /* */ 6449 /* */
6904 static void 6450 static void
6905 Ins_ISECT( INS_ARG ) 6451 Ins_ISECT( TT_ExecContext exc,
6452 FT_Long* args )
6906 { 6453 {
6907 FT_UShort point, 6454 FT_UShort point,
6908 a0, a1, 6455 a0, a1,
6909 b0, b1; 6456 b0, b1;
6910 6457
6911 FT_F26Dot6 discriminant, dotproduct; 6458 FT_F26Dot6 discriminant, dotproduct;
6912 6459
6913 FT_F26Dot6 dx, dy, 6460 FT_F26Dot6 dx, dy,
6914 dax, day, 6461 dax, day,
6915 dbx, dby; 6462 dbx, dby;
6916 6463
6917 FT_F26Dot6 val; 6464 FT_F26Dot6 val;
6918 6465
6919 FT_Vector R; 6466 FT_Vector R;
6920 6467
6921 6468
6922 point = (FT_UShort)args[0]; 6469 point = (FT_UShort)args[0];
6923 6470
6924 a0 = (FT_UShort)args[1]; 6471 a0 = (FT_UShort)args[1];
6925 a1 = (FT_UShort)args[2]; 6472 a1 = (FT_UShort)args[2];
6926 b0 = (FT_UShort)args[3]; 6473 b0 = (FT_UShort)args[3];
6927 b1 = (FT_UShort)args[4]; 6474 b1 = (FT_UShort)args[4];
6928 6475
6929 if ( BOUNDS( b0, CUR.zp0.n_points ) || 6476 if ( BOUNDS( b0, exc->zp0.n_points ) ||
6930 BOUNDS( b1, CUR.zp0.n_points ) || 6477 BOUNDS( b1, exc->zp0.n_points ) ||
6931 BOUNDS( a0, CUR.zp1.n_points ) || 6478 BOUNDS( a0, exc->zp1.n_points ) ||
6932 BOUNDS( a1, CUR.zp1.n_points ) || 6479 BOUNDS( a1, exc->zp1.n_points ) ||
6933 BOUNDS( point, CUR.zp2.n_points ) ) 6480 BOUNDS( point, exc->zp2.n_points ) )
6934 { 6481 {
6935 if ( CUR.pedantic_hinting ) 6482 if ( exc->pedantic_hinting )
6936 CUR.error = FT_THROW( Invalid_Reference ); 6483 exc->error = FT_THROW( Invalid_Reference );
6937 return; 6484 return;
6938 } 6485 }
6939 6486
6940 /* Cramer's rule */ 6487 /* Cramer's rule */
6941 6488
6942 dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; 6489 dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
6943 dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; 6490 dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
6944 6491
6945 dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; 6492 dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
6946 day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; 6493 day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
6947 6494
6948 dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; 6495 dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
6949 dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; 6496 dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
6950
6951 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
6952 6497
6953 discriminant = FT_MulDiv( dax, -dby, 0x40 ) + 6498 discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
6954 FT_MulDiv( day, dbx, 0x40 ); 6499 FT_MulDiv( day, dbx, 0x40 );
6955 dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + 6500 dotproduct = FT_MulDiv( dax, dbx, 0x40 ) +
6956 FT_MulDiv( day, dby, 0x40 ); 6501 FT_MulDiv( day, dby, 0x40 );
6957 6502
6958 /* The discriminant above is actually a cross product of vectors */ 6503 /* The discriminant above is actually a cross product of vectors */
6959 /* da and db. Together with the dot product, they can be used as */ 6504 /* da and db. Together with the dot product, they can be used as */
6960 /* surrogates for sine and cosine of the angle between the vectors. */ 6505 /* surrogates for sine and cosine of the angle between the vectors. */
6961 /* Indeed, */ 6506 /* Indeed, */
6962 /* dotproduct = |da||db|cos(angle) */ 6507 /* dotproduct = |da||db|cos(angle) */
6963 /* discriminant = |da||db|sin(angle) . */ 6508 /* discriminant = |da||db|sin(angle) . */
6964 /* We use these equations to reject grazing intersections by */ 6509 /* We use these equations to reject grazing intersections by */
6965 /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ 6510 /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */
6966 if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) 6511 if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) )
6967 { 6512 {
6968 val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); 6513 val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 );
6969 6514
6970 R.x = FT_MulDiv( val, dax, discriminant ); 6515 R.x = FT_MulDiv( val, dax, discriminant );
6971 R.y = FT_MulDiv( val, day, discriminant ); 6516 R.y = FT_MulDiv( val, day, discriminant );
6972 6517
6973 CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; 6518 exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
6974 CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; 6519 exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
6975 } 6520 }
6976 else 6521 else
6977 { 6522 {
6978 /* else, take the middle of the middles of A and B */ 6523 /* else, take the middle of the middles of A and B */
6979 6524
6980 CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + 6525 exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
6981 CUR.zp1.cur[a1].x + 6526 exc->zp1.cur[a1].x +
6982 CUR.zp0.cur[b0].x + 6527 exc->zp0.cur[b0].x +
6983 CUR.zp0.cur[b1].x ) / 4; 6528 exc->zp0.cur[b1].x ) / 4;
6984 CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + 6529 exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
6985 CUR.zp1.cur[a1].y + 6530 exc->zp1.cur[a1].y +
6986 CUR.zp0.cur[b0].y + 6531 exc->zp0.cur[b0].y +
6987 CUR.zp0.cur[b1].y ) / 4; 6532 exc->zp0.cur[b1].y ) / 4;
6988 } 6533 }
6534
6535 exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
6989 } 6536 }
6990 6537
6991 6538
6992 /*************************************************************************/ 6539 /*************************************************************************/
6993 /* */ 6540 /* */
6994 /* ALIGNPTS[]: ALIGN PoinTS */ 6541 /* ALIGNPTS[]: ALIGN PoinTS */
6995 /* Opcode range: 0x27 */ 6542 /* Opcode range: 0x27 */
6996 /* Stack: uint32 uint32 --> */ 6543 /* Stack: uint32 uint32 --> */
6997 /* */ 6544 /* */
6998 static void 6545 static void
6999 Ins_ALIGNPTS( INS_ARG ) 6546 Ins_ALIGNPTS( TT_ExecContext exc,
6547 FT_Long* args )
7000 { 6548 {
7001 FT_UShort p1, p2; 6549 FT_UShort p1, p2;
7002 FT_F26Dot6 distance; 6550 FT_F26Dot6 distance;
7003 6551
7004 6552
7005 p1 = (FT_UShort)args[0]; 6553 p1 = (FT_UShort)args[0];
7006 p2 = (FT_UShort)args[1]; 6554 p2 = (FT_UShort)args[1];
7007 6555
7008 if ( BOUNDS( p1, CUR.zp1.n_points ) || 6556 if ( BOUNDS( p1, exc->zp1.n_points ) ||
7009 BOUNDS( p2, CUR.zp0.n_points ) ) 6557 BOUNDS( p2, exc->zp0.n_points ) )
7010 { 6558 {
7011 if ( CUR.pedantic_hinting ) 6559 if ( exc->pedantic_hinting )
7012 CUR.error = FT_THROW( Invalid_Reference ); 6560 exc->error = FT_THROW( Invalid_Reference );
7013 return; 6561 return;
7014 } 6562 }
7015 6563
7016 distance = CUR_Func_project( CUR.zp0.cur + p2, 6564 distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
7017 CUR.zp1.cur + p1 ) / 2;
7018 6565
7019 CUR_Func_move( &CUR.zp1, p1, distance ); 6566 exc->func_move( exc, &exc->zp1, p1, distance );
7020 CUR_Func_move( &CUR.zp0, p2, -distance ); 6567 exc->func_move( exc, &exc->zp0, p2, -distance );
7021 } 6568 }
7022 6569
7023 6570
7024 /*************************************************************************/ 6571 /*************************************************************************/
7025 /* */ 6572 /* */
7026 /* IP[]: Interpolate Point */ 6573 /* IP[]: Interpolate Point */
7027 /* Opcode range: 0x39 */ 6574 /* Opcode range: 0x39 */
7028 /* Stack: uint32... --> */ 6575 /* Stack: uint32... --> */
7029 /* */ 6576 /* */
7030 6577
7031 /* SOMETIMES, DUMBER CODE IS BETTER CODE */ 6578 /* SOMETIMES, DUMBER CODE IS BETTER CODE */
7032 6579
7033 static void 6580 static void
7034 Ins_IP( INS_ARG ) 6581 Ins_IP( TT_ExecContext exc )
7035 { 6582 {
7036 FT_F26Dot6 old_range, cur_range; 6583 FT_F26Dot6 old_range, cur_range;
7037 FT_Vector* orus_base; 6584 FT_Vector* orus_base;
7038 FT_Vector* cur_base; 6585 FT_Vector* cur_base;
7039 FT_Int twilight; 6586 FT_Int twilight;
7040 6587
7041 FT_UNUSED_ARG;
7042 6588
7043 6589 if ( exc->top < exc->GS.loop )
7044 if ( CUR.top < CUR.GS.loop )
7045 { 6590 {
7046 if ( CUR.pedantic_hinting ) 6591 if ( exc->pedantic_hinting )
7047 CUR.error = FT_THROW( Invalid_Reference ); 6592 exc->error = FT_THROW( Invalid_Reference );
7048 goto Fail; 6593 goto Fail;
7049 } 6594 }
7050 6595
7051 /* 6596 /*
7052 * We need to deal in a special way with the twilight zone. 6597 * We need to deal in a special way with the twilight zone.
7053 * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), 6598 * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
7054 * for every n. 6599 * for every n.
7055 */ 6600 */
7056 twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; 6601 twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
7057 6602
7058 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) 6603 if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
7059 { 6604 {
7060 if ( CUR.pedantic_hinting ) 6605 if ( exc->pedantic_hinting )
7061 CUR.error = FT_THROW( Invalid_Reference ); 6606 exc->error = FT_THROW( Invalid_Reference );
7062 goto Fail; 6607 goto Fail;
7063 } 6608 }
7064 6609
7065 if ( twilight ) 6610 if ( twilight )
7066 orus_base = &CUR.zp0.org[CUR.GS.rp1]; 6611 orus_base = &exc->zp0.org[exc->GS.rp1];
7067 else 6612 else
7068 orus_base = &CUR.zp0.orus[CUR.GS.rp1]; 6613 orus_base = &exc->zp0.orus[exc->GS.rp1];
7069 6614
7070 cur_base = &CUR.zp0.cur[CUR.GS.rp1]; 6615 cur_base = &exc->zp0.cur[exc->GS.rp1];
7071 6616
7072 /* XXX: There are some glyphs in some braindead but popular */ 6617 /* XXX: There are some glyphs in some braindead but popular */
7073 /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ 6618 /* fonts out there (e.g. [aeu]grave in monotype.ttf) */
7074 /* calling IP[] with bad values of rp[12]. */ 6619 /* calling IP[] with bad values of rp[12]. */
7075 /* Do something sane when this odd thing happens. */ 6620 /* Do something sane when this odd thing happens. */
7076 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || 6621 if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
7077 BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) 6622 BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
7078 { 6623 {
7079 old_range = 0; 6624 old_range = 0;
7080 cur_range = 0; 6625 cur_range = 0;
7081 } 6626 }
7082 else 6627 else
7083 { 6628 {
7084 if ( twilight ) 6629 if ( twilight )
7085 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], 6630 old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base );
7086 orus_base ); 6631 else if ( exc->metrics.x_scale == exc->metrics.y_scale )
7087 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) 6632 old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base );
7088 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
7089 orus_base );
7090 else 6633 else
7091 { 6634 {
7092 FT_Vector vec; 6635 FT_Vector vec;
7093 6636
7094 6637
7095 vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, 6638 vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
7096 CUR.metrics.x_scale ); 6639 exc->metrics.x_scale );
7097 vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, 6640 vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
7098 CUR.metrics.y_scale ); 6641 exc->metrics.y_scale );
7099 6642
7100 old_range = CUR_fast_dualproj( &vec ); 6643 old_range = FAST_DUALPROJ( &vec );
7101 } 6644 }
7102 6645
7103 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); 6646 cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
7104 } 6647 }
7105 6648
7106 for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) 6649 for ( ; exc->GS.loop > 0; --exc->GS.loop )
7107 { 6650 {
7108 FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; 6651 FT_UInt point = (FT_UInt)exc->stack[--exc->args];
7109 FT_F26Dot6 org_dist, cur_dist, new_dist; 6652 FT_F26Dot6 org_dist, cur_dist, new_dist;
7110 6653
7111 6654
7112 /* check point bounds */ 6655 /* check point bounds */
7113 if ( BOUNDS( point, CUR.zp2.n_points ) ) 6656 if ( BOUNDS( point, exc->zp2.n_points ) )
7114 { 6657 {
7115 if ( CUR.pedantic_hinting ) 6658 if ( exc->pedantic_hinting )
7116 { 6659 {
7117 CUR.error = FT_THROW( Invalid_Reference ); 6660 exc->error = FT_THROW( Invalid_Reference );
7118 return; 6661 return;
7119 } 6662 }
7120 continue; 6663 continue;
7121 } 6664 }
7122 6665
7123 if ( twilight ) 6666 if ( twilight )
7124 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); 6667 org_dist = DUALPROJ( &exc->zp2.org[point], orus_base );
7125 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) 6668 else if ( exc->metrics.x_scale == exc->metrics.y_scale )
7126 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); 6669 org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base );
7127 else 6670 else
7128 { 6671 {
7129 FT_Vector vec; 6672 FT_Vector vec;
7130 6673
7131 6674
7132 vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, 6675 vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
7133 CUR.metrics.x_scale ); 6676 exc->metrics.x_scale );
7134 vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, 6677 vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
7135 CUR.metrics.y_scale ); 6678 exc->metrics.y_scale );
7136 6679
7137 org_dist = CUR_fast_dualproj( &vec ); 6680 org_dist = FAST_DUALPROJ( &vec );
7138 } 6681 }
7139 6682
7140 cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base ); 6683 cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
7141 6684
7142 if ( org_dist ) 6685 if ( org_dist )
7143 { 6686 {
7144 if ( old_range ) 6687 if ( old_range )
7145 new_dist = FT_MulDiv( org_dist, cur_range, old_range ); 6688 new_dist = FT_MulDiv( org_dist, cur_range, old_range );
7146 else 6689 else
7147 { 6690 {
7148 /* This is the same as what MS does for the invalid case: */ 6691 /* This is the same as what MS does for the invalid case: */
7149 /* */ 6692 /* */
7150 /* delta = (Original_Pt - Original_RP1) - */ 6693 /* delta = (Original_Pt - Original_RP1) - */
7151 /* (Current_Pt - Current_RP1) ; */ 6694 /* (Current_Pt - Current_RP1) ; */
7152 /* */ 6695 /* */
7153 /* In FreeType speak: */ 6696 /* In FreeType speak: */
7154 /* */ 6697 /* */
7155 /* delta = org_dist - cur_dist . */ 6698 /* delta = org_dist - cur_dist . */
7156 /* */ 6699 /* */
7157 /* We move `point' by `new_dist - cur_dist' after leaving */ 6700 /* We move `point' by `new_dist - cur_dist' after leaving */
7158 /* this block, thus we have */ 6701 /* this block, thus we have */
7159 /* */ 6702 /* */
7160 /* new_dist - cur_dist = delta , */ 6703 /* new_dist - cur_dist = delta , */
7161 /* new_dist - cur_dist = org_dist - cur_dist , */ 6704 /* new_dist - cur_dist = org_dist - cur_dist , */
7162 /* new_dist = org_dist . */ 6705 /* new_dist = org_dist . */
7163 6706
7164 new_dist = org_dist; 6707 new_dist = org_dist;
7165 } 6708 }
7166 } 6709 }
7167 else 6710 else
7168 new_dist = 0; 6711 new_dist = 0;
7169 6712
7170 CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); 6713 exc->func_move( exc,
6714 &exc->zp2,
6715 (FT_UShort)point,
6716 new_dist - cur_dist );
7171 } 6717 }
7172 6718
7173 Fail: 6719 Fail:
7174 CUR.GS.loop = 1; 6720 exc->GS.loop = 1;
7175 CUR.new_top = CUR.args; 6721 exc->new_top = exc->args;
7176 } 6722 }
7177 6723
7178 6724
7179 /*************************************************************************/ 6725 /*************************************************************************/
7180 /* */ 6726 /* */
7181 /* UTP[a]: UnTouch Point */ 6727 /* UTP[a]: UnTouch Point */
7182 /* Opcode range: 0x29 */ 6728 /* Opcode range: 0x29 */
7183 /* Stack: uint32 --> */ 6729 /* Stack: uint32 --> */
7184 /* */ 6730 /* */
7185 static void 6731 static void
7186 Ins_UTP( INS_ARG ) 6732 Ins_UTP( TT_ExecContext exc,
6733 FT_Long* args )
7187 { 6734 {
7188 FT_UShort point; 6735 FT_UShort point;
7189 FT_Byte mask; 6736 FT_Byte mask;
7190 6737
7191 6738
7192 point = (FT_UShort)args[0]; 6739 point = (FT_UShort)args[0];
7193 6740
7194 if ( BOUNDS( point, CUR.zp0.n_points ) ) 6741 if ( BOUNDS( point, exc->zp0.n_points ) )
7195 { 6742 {
7196 if ( CUR.pedantic_hinting ) 6743 if ( exc->pedantic_hinting )
7197 CUR.error = FT_THROW( Invalid_Reference ); 6744 exc->error = FT_THROW( Invalid_Reference );
7198 return; 6745 return;
7199 } 6746 }
7200 6747
7201 mask = 0xFF; 6748 mask = 0xFF;
7202 6749
7203 if ( CUR.GS.freeVector.x != 0 ) 6750 if ( exc->GS.freeVector.x != 0 )
7204 mask &= ~FT_CURVE_TAG_TOUCH_X; 6751 mask &= ~FT_CURVE_TAG_TOUCH_X;
7205 6752
7206 if ( CUR.GS.freeVector.y != 0 ) 6753 if ( exc->GS.freeVector.y != 0 )
7207 mask &= ~FT_CURVE_TAG_TOUCH_Y; 6754 mask &= ~FT_CURVE_TAG_TOUCH_Y;
7208 6755
7209 CUR.zp0.tags[point] &= mask; 6756 exc->zp0.tags[point] &= mask;
7210 } 6757 }
7211 6758
7212 6759
7213 /* Local variables for Ins_IUP: */ 6760 /* Local variables for Ins_IUP: */
7214 typedef struct IUP_WorkerRec_ 6761 typedef struct IUP_WorkerRec_
7215 { 6762 {
7216 FT_Vector* orgs; /* original and current coordinate */ 6763 FT_Vector* orgs; /* original and current coordinate */
7217 FT_Vector* curs; /* arrays */ 6764 FT_Vector* curs; /* arrays */
7218 FT_Vector* orus; 6765 FT_Vector* orus;
7219 FT_UInt max_points; 6766 FT_UInt max_points;
(...skipping 24 matching lines...) Expand all
7244 6791
7245 6792
7246 static void 6793 static void
7247 _iup_worker_interpolate( IUP_Worker worker, 6794 _iup_worker_interpolate( IUP_Worker worker,
7248 FT_UInt p1, 6795 FT_UInt p1,
7249 FT_UInt p2, 6796 FT_UInt p2,
7250 FT_UInt ref1, 6797 FT_UInt ref1,
7251 FT_UInt ref2 ) 6798 FT_UInt ref2 )
7252 { 6799 {
7253 FT_UInt i; 6800 FT_UInt i;
7254 FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; 6801 FT_F26Dot6 orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
7255 6802
7256 6803
7257 if ( p1 > p2 ) 6804 if ( p1 > p2 )
7258 return; 6805 return;
7259 6806
7260 if ( BOUNDS( ref1, worker->max_points ) || 6807 if ( BOUNDS( ref1, worker->max_points ) ||
7261 BOUNDS( ref2, worker->max_points ) ) 6808 BOUNDS( ref2, worker->max_points ) )
7262 return; 6809 return;
7263 6810
7264 orus1 = worker->orus[ref1].x; 6811 orus1 = worker->orus[ref1].x;
7265 orus2 = worker->orus[ref2].x; 6812 orus2 = worker->orus[ref2].x;
7266 6813
7267 if ( orus1 > orus2 ) 6814 if ( orus1 > orus2 )
7268 { 6815 {
7269 FT_F26Dot6 tmp_o; 6816 FT_F26Dot6 tmp_o;
7270 FT_UInt tmp_r; 6817 FT_UInt tmp_r;
7271 6818
7272 6819
7273 tmp_o = orus1; 6820 tmp_o = orus1;
7274 orus1 = orus2; 6821 orus1 = orus2;
7275 orus2 = tmp_o; 6822 orus2 = tmp_o;
7276 6823
7277 tmp_r = ref1; 6824 tmp_r = ref1;
7278 ref1 = ref2; 6825 ref1 = ref2;
7279 ref2 = tmp_r; 6826 ref2 = tmp_r;
7280 } 6827 }
7281 6828
7282 org1 = worker->orgs[ref1].x; 6829 org1 = worker->orgs[ref1].x;
7283 org2 = worker->orgs[ref2].x; 6830 org2 = worker->orgs[ref2].x;
7284 delta1 = worker->curs[ref1].x - org1; 6831 cur1 = worker->curs[ref1].x;
7285 delta2 = worker->curs[ref2].x - org2; 6832 cur2 = worker->curs[ref2].x;
6833 delta1 = cur1 - org1;
6834 delta2 = cur2 - org2;
7286 6835
7287 if ( orus1 == orus2 ) 6836 if ( cur1 == cur2 || orus1 == orus2 )
7288 { 6837 {
7289 /* simple shift of untouched points */ 6838
6839 /* trivial snap or shift of untouched points */
7290 for ( i = p1; i <= p2; i++ ) 6840 for ( i = p1; i <= p2; i++ )
7291 { 6841 {
7292 FT_F26Dot6 x = worker->orgs[i].x; 6842 FT_F26Dot6 x = worker->orgs[i].x;
7293 6843
7294 6844
7295 if ( x <= org1 ) 6845 if ( x <= org1 )
7296 x += delta1; 6846 x += delta1;
6847
6848 else if ( x >= org2 )
6849 x += delta2;
6850
7297 else 6851 else
7298 x += delta2; 6852 x = cur1;
7299 6853
7300 worker->curs[i].x = x; 6854 worker->curs[i].x = x;
7301 } 6855 }
7302 } 6856 }
7303 else 6857 else
7304 { 6858 {
7305 FT_Fixed scale = 0; 6859 FT_Fixed scale = 0;
7306 FT_Bool scale_valid = 0; 6860 FT_Bool scale_valid = 0;
7307 6861
7308 6862
7309 /* interpolation */ 6863 /* interpolation */
7310 for ( i = p1; i <= p2; i++ ) 6864 for ( i = p1; i <= p2; i++ )
7311 { 6865 {
7312 FT_F26Dot6 x = worker->orgs[i].x; 6866 FT_F26Dot6 x = worker->orgs[i].x;
7313 6867
7314 6868
7315 if ( x <= org1 ) 6869 if ( x <= org1 )
7316 x += delta1; 6870 x += delta1;
7317 6871
7318 else if ( x >= org2 ) 6872 else if ( x >= org2 )
7319 x += delta2; 6873 x += delta2;
7320 6874
7321 else 6875 else
7322 { 6876 {
7323 if ( !scale_valid ) 6877 if ( !scale_valid )
7324 { 6878 {
7325 scale_valid = 1; 6879 scale_valid = 1;
7326 scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), 6880 scale = FT_DivFix( cur2 - cur1, orus2 - orus1 );
7327 orus2 - orus1 );
7328 } 6881 }
7329 6882
7330 x = ( org1 + delta1 ) + 6883 x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
7331 FT_MulFix( worker->orus[i].x - orus1, scale );
7332 } 6884 }
7333 worker->curs[i].x = x; 6885 worker->curs[i].x = x;
7334 } 6886 }
7335 } 6887 }
7336 } 6888 }
7337 6889
7338 6890
7339 /*************************************************************************/ 6891 /*************************************************************************/
7340 /* */ 6892 /* */
7341 /* IUP[a]: Interpolate Untouched Points */ 6893 /* IUP[a]: Interpolate Untouched Points */
7342 /* Opcode range: 0x30-0x31 */ 6894 /* Opcode range: 0x30-0x31 */
7343 /* Stack: --> */ 6895 /* Stack: --> */
7344 /* */ 6896 /* */
7345 static void 6897 static void
7346 Ins_IUP( INS_ARG ) 6898 Ins_IUP( TT_ExecContext exc )
7347 { 6899 {
7348 IUP_WorkerRec V; 6900 IUP_WorkerRec V;
7349 FT_Byte mask; 6901 FT_Byte mask;
7350 6902
7351 FT_UInt first_point; /* first point of contour */ 6903 FT_UInt first_point; /* first point of contour */
7352 FT_UInt end_point; /* end point (last+1) of contour */ 6904 FT_UInt end_point; /* end point (last+1) of contour */
7353 6905
7354 FT_UInt first_touched; /* first touched point in contour */ 6906 FT_UInt first_touched; /* first touched point in contour */
7355 FT_UInt cur_touched; /* current touched point in contour */ 6907 FT_UInt cur_touched; /* current touched point in contour */
7356 6908
7357 FT_UInt point; /* current point */ 6909 FT_UInt point; /* current point */
7358 FT_Short contour; /* current contour */ 6910 FT_Short contour; /* current contour */
7359 6911
7360 FT_UNUSED_ARG;
7361
7362 6912
7363 /* ignore empty outlines */ 6913 /* ignore empty outlines */
7364 if ( CUR.pts.n_contours == 0 ) 6914 if ( exc->pts.n_contours == 0 )
7365 return; 6915 return;
7366 6916
7367 if ( CUR.opcode & 1 ) 6917 if ( exc->opcode & 1 )
7368 { 6918 {
7369 mask = FT_CURVE_TAG_TOUCH_X; 6919 mask = FT_CURVE_TAG_TOUCH_X;
7370 V.orgs = CUR.pts.org; 6920 V.orgs = exc->pts.org;
7371 V.curs = CUR.pts.cur; 6921 V.curs = exc->pts.cur;
7372 V.orus = CUR.pts.orus; 6922 V.orus = exc->pts.orus;
7373 } 6923 }
7374 else 6924 else
7375 { 6925 {
7376 mask = FT_CURVE_TAG_TOUCH_Y; 6926 mask = FT_CURVE_TAG_TOUCH_Y;
7377 V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); 6927 V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
7378 V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); 6928 V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
7379 V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); 6929 V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
7380 } 6930 }
7381 V.max_points = CUR.pts.n_points; 6931 V.max_points = exc->pts.n_points;
7382 6932
7383 contour = 0; 6933 contour = 0;
7384 point = 0; 6934 point = 0;
7385 6935
7386 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6936 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7387 if ( SUBPIXEL_HINTING && 6937 if ( SUBPIXEL_HINTING &&
7388 CUR.ignore_x_mode ) 6938 exc->ignore_x_mode )
7389 { 6939 {
7390 CUR.iup_called = TRUE; 6940 exc->iup_called = TRUE;
7391 if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) 6941 if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
7392 return; 6942 return;
7393 } 6943 }
7394 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6944 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
7395 6945
7396 do 6946 do
7397 { 6947 {
7398 end_point = CUR.pts.contours[contour] - CUR.pts.first_point; 6948 end_point = exc->pts.contours[contour] - exc->pts.first_point;
7399 first_point = point; 6949 first_point = point;
7400 6950
7401 if ( BOUNDS ( end_point, CUR.pts.n_points ) ) 6951 if ( BOUNDS( end_point, exc->pts.n_points ) )
7402 end_point = CUR.pts.n_points - 1; 6952 end_point = exc->pts.n_points - 1;
7403 6953
7404 while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) 6954 while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
7405 point++; 6955 point++;
7406 6956
7407 if ( point <= end_point ) 6957 if ( point <= end_point )
7408 { 6958 {
7409 first_touched = point; 6959 first_touched = point;
7410 cur_touched = point; 6960 cur_touched = point;
7411 6961
7412 point++; 6962 point++;
7413 6963
7414 while ( point <= end_point ) 6964 while ( point <= end_point )
7415 { 6965 {
7416 if ( ( CUR.pts.tags[point] & mask ) != 0 ) 6966 if ( ( exc->pts.tags[point] & mask ) != 0 )
7417 { 6967 {
7418 _iup_worker_interpolate( &V, 6968 _iup_worker_interpolate( &V,
7419 cur_touched + 1, 6969 cur_touched + 1,
7420 point - 1, 6970 point - 1,
7421 cur_touched, 6971 cur_touched,
7422 point ); 6972 point );
7423 cur_touched = point; 6973 cur_touched = point;
7424 } 6974 }
7425 6975
7426 point++; 6976 point++;
(...skipping 11 matching lines...) Expand all
7438 6988
7439 if ( first_touched > 0 ) 6989 if ( first_touched > 0 )
7440 _iup_worker_interpolate( &V, 6990 _iup_worker_interpolate( &V,
7441 first_point, 6991 first_point,
7442 first_touched - 1, 6992 first_touched - 1,
7443 cur_touched, 6993 cur_touched,
7444 first_touched ); 6994 first_touched );
7445 } 6995 }
7446 } 6996 }
7447 contour++; 6997 contour++;
7448 } while ( contour < CUR.pts.n_contours ); 6998 } while ( contour < exc->pts.n_contours );
7449 } 6999 }
7450 7000
7451 7001
7452 /*************************************************************************/ 7002 /*************************************************************************/
7453 /* */ 7003 /* */
7454 /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ 7004 /* DELTAPn[]: DELTA exceptions P1, P2, P3 */
7455 /* Opcode range: 0x5D,0x71,0x72 */ 7005 /* Opcode range: 0x5D,0x71,0x72 */
7456 /* Stack: uint32 (2 * uint32)... --> */ 7006 /* Stack: uint32 (2 * uint32)... --> */
7457 /* */ 7007 /* */
7458 static void 7008 static void
7459 Ins_DELTAP( INS_ARG ) 7009 Ins_DELTAP( TT_ExecContext exc,
7010 FT_Long* args )
7460 { 7011 {
7461 FT_ULong nump, k; 7012 FT_ULong nump, k;
7462 FT_UShort A; 7013 FT_UShort A;
7463 FT_ULong C, P; 7014 FT_ULong C, P;
7464 FT_Long B; 7015 FT_Long B;
7465 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7016 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7466 FT_UShort B1, B2; 7017 FT_UShort B1, B2;
7467 7018
7468 7019
7469 if ( SUBPIXEL_HINTING && 7020 if ( SUBPIXEL_HINTING &&
7470 CUR.ignore_x_mode && 7021 exc->ignore_x_mode &&
7471 CUR.iup_called && 7022 exc->iup_called &&
7472 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) 7023 ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
7473 goto Fail; 7024 goto Fail;
7474 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7025 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
7475 7026
7476 7027
7477 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 7028 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
7478 /* Delta hinting is covered by US Patent 5159668. */ 7029 /* Delta hinting is covered by US Patent 5159668. */
7479 if ( CUR.face->unpatented_hinting ) 7030 if ( exc->face->unpatented_hinting )
7480 { 7031 {
7481 FT_Long n = args[0] * 2; 7032 FT_Long n = args[0] * 2;
7482 7033
7483 7034
7484 if ( CUR.args < n ) 7035 if ( exc->args < n )
7485 { 7036 {
7486 if ( CUR.pedantic_hinting ) 7037 if ( exc->pedantic_hinting )
7487 CUR.error = FT_THROW( Too_Few_Arguments ); 7038 exc->error = FT_THROW( Too_Few_Arguments );
7488 n = CUR.args; 7039 n = exc->args;
7489 } 7040 }
7490 7041
7491 CUR.args -= n; 7042 exc->args -= n;
7492 CUR.new_top = CUR.args; 7043 exc->new_top = exc->args;
7493 return; 7044 return;
7494 } 7045 }
7495 #endif 7046 #endif
7496 7047
7497 P = (FT_ULong)CUR_Func_cur_ppem(); 7048 P = (FT_ULong)exc->func_cur_ppem( exc );
7498 nump = (FT_ULong)args[0]; /* some points theoretically may occur more 7049 nump = (FT_ULong)args[0]; /* some points theoretically may occur more
7499 than once, thus UShort isn't enough */ 7050 than once, thus UShort isn't enough */
7500 7051
7501 for ( k = 1; k <= nump; k++ ) 7052 for ( k = 1; k <= nump; k++ )
7502 { 7053 {
7503 if ( CUR.args < 2 ) 7054 if ( exc->args < 2 )
7504 { 7055 {
7505 if ( CUR.pedantic_hinting ) 7056 if ( exc->pedantic_hinting )
7506 CUR.error = FT_THROW( Too_Few_Arguments ); 7057 exc->error = FT_THROW( Too_Few_Arguments );
7507 CUR.args = 0; 7058 exc->args = 0;
7508 goto Fail; 7059 goto Fail;
7509 } 7060 }
7510 7061
7511 CUR.args -= 2; 7062 exc->args -= 2;
7512 7063
7513 A = (FT_UShort)CUR.stack[CUR.args + 1]; 7064 A = (FT_UShort)exc->stack[exc->args + 1];
7514 B = CUR.stack[CUR.args]; 7065 B = exc->stack[exc->args];
7515 7066
7516 /* XXX: Because some popular fonts contain some invalid DeltaP */ 7067 /* XXX: Because some popular fonts contain some invalid DeltaP */
7517 /* instructions, we simply ignore them when the stacked */ 7068 /* instructions, we simply ignore them when the stacked */
7518 /* point reference is off limit, rather than returning an */ 7069 /* point reference is off limit, rather than returning an */
7519 /* error. As a delta instruction doesn't change a glyph */ 7070 /* error. As a delta instruction doesn't change a glyph */
7520 /* in great ways, this shouldn't be a problem. */ 7071 /* in great ways, this shouldn't be a problem. */
7521 7072
7522 if ( !BOUNDS( A, CUR.zp0.n_points ) ) 7073 if ( !BOUNDS( A, exc->zp0.n_points ) )
7523 { 7074 {
7524 C = ( (FT_ULong)B & 0xF0 ) >> 4; 7075 C = ( (FT_ULong)B & 0xF0 ) >> 4;
7525 7076
7526 switch ( CUR.opcode ) 7077 switch ( exc->opcode )
7527 { 7078 {
7528 case 0x5D: 7079 case 0x5D:
7529 break; 7080 break;
7530 7081
7531 case 0x71: 7082 case 0x71:
7532 C += 16; 7083 C += 16;
7533 break; 7084 break;
7534 7085
7535 case 0x72: 7086 case 0x72:
7536 C += 32; 7087 C += 32;
7537 break; 7088 break;
7538 } 7089 }
7539 7090
7540 C += CUR.GS.delta_base; 7091 C += exc->GS.delta_base;
7541 7092
7542 if ( P == C ) 7093 if ( P == C )
7543 { 7094 {
7544 B = ( (FT_ULong)B & 0xF ) - 8; 7095 B = ( (FT_ULong)B & 0xF ) - 8;
7545 if ( B >= 0 ) 7096 if ( B >= 0 )
7546 B++; 7097 B++;
7547 B *= 1L << ( 6 - CUR.GS.delta_shift ); 7098 B *= 1L << ( 6 - exc->GS.delta_shift );
7548 7099
7549 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7100 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7550 7101
7551 if ( SUBPIXEL_HINTING ) 7102 if ( SUBPIXEL_HINTING )
7552 { 7103 {
7553 /* 7104 /*
7554 * Allow delta move if 7105 * Allow delta move if
7555 * 7106 *
7556 * - not using ignore_x_mode rendering, 7107 * - not using ignore_x_mode rendering,
7557 * - glyph is specifically set to allow it, or 7108 * - glyph is specifically set to allow it, or
7558 * - glyph is composite and freedom vector is not in subpixel 7109 * - glyph is composite and freedom vector is not in subpixel
7559 * direction. 7110 * direction.
7560 */ 7111 */
7561 if ( !CUR.ignore_x_mode || 7112 if ( !exc->ignore_x_mode ||
7562 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || 7113 ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
7563 ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) 7114 ( exc->is_composite && exc->GS.freeVector.y != 0 ) )
7564 CUR_Func_move( &CUR.zp0, A, B ); 7115 exc->func_move( exc, &exc->zp0, A, B );
7565 7116
7566 /* Otherwise, apply subpixel hinting and compatibility mode */ 7117 /* Otherwise, apply subpixel hinting and compatibility mode */
7567 /* rules, always skipping deltas in subpixel direction. */ 7118 /* rules, always skipping deltas in subpixel direction. */
7568 else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 ) 7119 else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
7569 { 7120 {
7570 /* save the y value of the point now; compare after move */ 7121 /* save the y value of the point now; compare after move */
7571 B1 = (FT_UShort)CUR.zp0.cur[A].y; 7122 B1 = (FT_UShort)exc->zp0.cur[A].y;
7572 7123
7573 /* Standard subpixel hinting: Allow y move for y-touched */ 7124 /* Standard subpixel hinting: Allow y move for y-touched */
7574 /* points. This messes up DejaVu ... */ 7125 /* points. This messes up DejaVu ... */
7575 if ( !CUR.face->sph_compatibility_mode && 7126 if ( !exc->face->sph_compatibility_mode &&
7576 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) 7127 ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
7577 CUR_Func_move( &CUR.zp0, A, B ); 7128 exc->func_move( exc, &exc->zp0, A, B );
7578 7129
7579 /* compatibility mode */ 7130 /* compatibility mode */
7580 else if ( CUR.face->sph_compatibility_mode && 7131 else if ( exc->face->sph_compatibility_mode &&
7581 !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) 7132 !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
7582 { 7133 {
7583 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) 7134 if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
7584 B = FT_PIX_ROUND( B1 + B ) - B1; 7135 B = FT_PIX_ROUND( B1 + B ) - B1;
7585 7136
7586 /* Allow delta move if using sph_compatibility_mode, */ 7137 /* Allow delta move if using sph_compatibility_mode, */
7587 /* IUP has not been called, and point is touched on Y. */ 7138 /* IUP has not been called, and point is touched on Y. */
7588 if ( !CUR.iup_called && 7139 if ( !exc->iup_called &&
7589 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) 7140 ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
7590 CUR_Func_move( &CUR.zp0, A, B ); 7141 exc->func_move( exc, &exc->zp0, A, B );
7591 } 7142 }
7592 7143
7593 B2 = (FT_UShort)CUR.zp0.cur[A].y; 7144 B2 = (FT_UShort)exc->zp0.cur[A].y;
7594 7145
7595 /* Reverse this move if it results in a disallowed move */ 7146 /* Reverse this move if it results in a disallowed move */
7596 if ( CUR.GS.freeVector.y != 0 && 7147 if ( exc->GS.freeVector.y != 0 &&
7597 ( ( CUR.face->sph_compatibility_mode && 7148 ( ( exc->face->sph_compatibility_mode &&
7598 ( B1 & 63 ) == 0 && 7149 ( B1 & 63 ) == 0 &&
7599 ( B2 & 63 ) != 0 ) || 7150 ( B2 & 63 ) != 0 ) ||
7600 ( ( CUR.sph_tweak_flags & 7151 ( ( exc->sph_tweak_flags &
7601 SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && 7152 SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
7602 ( B1 & 63 ) != 0 && 7153 ( B1 & 63 ) != 0 &&
7603 ( B2 & 63 ) != 0 ) ) ) 7154 ( B2 & 63 ) != 0 ) ) )
7604 CUR_Func_move( &CUR.zp0, A, -B ); 7155 exc->func_move( exc, &exc->zp0, A, -B );
7605 } 7156 }
7606 } 7157 }
7607 else 7158 else
7608 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7159 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
7609 7160
7610 CUR_Func_move( &CUR.zp0, A, B ); 7161 exc->func_move( exc, &exc->zp0, A, B );
7611 } 7162 }
7612 } 7163 }
7613 else 7164 else
7614 if ( CUR.pedantic_hinting ) 7165 if ( exc->pedantic_hinting )
7615 CUR.error = FT_THROW( Invalid_Reference ); 7166 exc->error = FT_THROW( Invalid_Reference );
7616 } 7167 }
7617 7168
7618 Fail: 7169 Fail:
7619 CUR.new_top = CUR.args; 7170 exc->new_top = exc->args;
7620 } 7171 }
7621 7172
7622 7173
7623 /*************************************************************************/ 7174 /*************************************************************************/
7624 /* */ 7175 /* */
7625 /* DELTACn[]: DELTA exceptions C1, C2, C3 */ 7176 /* DELTACn[]: DELTA exceptions C1, C2, C3 */
7626 /* Opcode range: 0x73,0x74,0x75 */ 7177 /* Opcode range: 0x73,0x74,0x75 */
7627 /* Stack: uint32 (2 * uint32)... --> */ 7178 /* Stack: uint32 (2 * uint32)... --> */
7628 /* */ 7179 /* */
7629 static void 7180 static void
7630 Ins_DELTAC( INS_ARG ) 7181 Ins_DELTAC( TT_ExecContext exc,
7182 FT_Long* args )
7631 { 7183 {
7632 FT_ULong nump, k; 7184 FT_ULong nump, k;
7633 FT_ULong A, C, P; 7185 FT_ULong A, C, P;
7634 FT_Long B; 7186 FT_Long B;
7635 7187
7636 7188
7637 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 7189 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
7638 /* Delta hinting is covered by US Patent 5159668. */ 7190 /* Delta hinting is covered by US Patent 5159668. */
7639 if ( CUR.face->unpatented_hinting ) 7191 if ( exc->face->unpatented_hinting )
7640 { 7192 {
7641 FT_Long n = args[0] * 2; 7193 FT_Long n = args[0] * 2;
7642 7194
7643 7195
7644 if ( CUR.args < n ) 7196 if ( exc->args < n )
7645 { 7197 {
7646 if ( CUR.pedantic_hinting ) 7198 if ( exc->pedantic_hinting )
7647 CUR.error = FT_THROW( Too_Few_Arguments ); 7199 exc->error = FT_THROW( Too_Few_Arguments );
7648 n = CUR.args; 7200 n = exc->args;
7649 } 7201 }
7650 7202
7651 CUR.args -= n; 7203 exc->args -= n;
7652 CUR.new_top = CUR.args; 7204 exc->new_top = exc->args;
7653 return; 7205 return;
7654 } 7206 }
7655 #endif 7207 #endif
7656 7208
7657 P = (FT_ULong)CUR_Func_cur_ppem(); 7209 P = (FT_ULong)exc->func_cur_ppem( exc );
7658 nump = (FT_ULong)args[0]; 7210 nump = (FT_ULong)args[0];
7659 7211
7660 for ( k = 1; k <= nump; k++ ) 7212 for ( k = 1; k <= nump; k++ )
7661 { 7213 {
7662 if ( CUR.args < 2 ) 7214 if ( exc->args < 2 )
7663 { 7215 {
7664 if ( CUR.pedantic_hinting ) 7216 if ( exc->pedantic_hinting )
7665 CUR.error = FT_THROW( Too_Few_Arguments ); 7217 exc->error = FT_THROW( Too_Few_Arguments );
7666 CUR.args = 0; 7218 exc->args = 0;
7667 goto Fail; 7219 goto Fail;
7668 } 7220 }
7669 7221
7670 CUR.args -= 2; 7222 exc->args -= 2;
7671 7223
7672 A = (FT_ULong)CUR.stack[CUR.args + 1]; 7224 A = (FT_ULong)exc->stack[exc->args + 1];
7673 B = CUR.stack[CUR.args]; 7225 B = exc->stack[exc->args];
7674 7226
7675 if ( BOUNDSL( A, CUR.cvtSize ) ) 7227 if ( BOUNDSL( A, exc->cvtSize ) )
7676 { 7228 {
7677 if ( CUR.pedantic_hinting ) 7229 if ( exc->pedantic_hinting )
7678 { 7230 {
7679 CUR.error = FT_THROW( Invalid_Reference ); 7231 exc->error = FT_THROW( Invalid_Reference );
7680 return; 7232 return;
7681 } 7233 }
7682 } 7234 }
7683 else 7235 else
7684 { 7236 {
7685 C = ( (FT_ULong)B & 0xF0 ) >> 4; 7237 C = ( (FT_ULong)B & 0xF0 ) >> 4;
7686 7238
7687 switch ( CUR.opcode ) 7239 switch ( exc->opcode )
7688 { 7240 {
7689 case 0x73: 7241 case 0x73:
7690 break; 7242 break;
7691 7243
7692 case 0x74: 7244 case 0x74:
7693 C += 16; 7245 C += 16;
7694 break; 7246 break;
7695 7247
7696 case 0x75: 7248 case 0x75:
7697 C += 32; 7249 C += 32;
7698 break; 7250 break;
7699 } 7251 }
7700 7252
7701 C += CUR.GS.delta_base; 7253 C += exc->GS.delta_base;
7702 7254
7703 if ( P == C ) 7255 if ( P == C )
7704 { 7256 {
7705 B = ( (FT_ULong)B & 0xF ) - 8; 7257 B = ( (FT_ULong)B & 0xF ) - 8;
7706 if ( B >= 0 ) 7258 if ( B >= 0 )
7707 B++; 7259 B++;
7708 B *= 1L << ( 6 - CUR.GS.delta_shift ); 7260 B *= 1L << ( 6 - exc->GS.delta_shift );
7709 7261
7710 CUR_Func_move_cvt( A, B ); 7262 exc->func_move_cvt( exc, A, B );
7711 } 7263 }
7712 } 7264 }
7713 } 7265 }
7714 7266
7715 Fail: 7267 Fail:
7716 CUR.new_top = CUR.args; 7268 exc->new_top = exc->args;
7717 } 7269 }
7718 7270
7719 7271
7720 /*************************************************************************/ 7272 /*************************************************************************/
7721 /* */ 7273 /* */
7722 /* MISC. INSTRUCTIONS */ 7274 /* MISC. INSTRUCTIONS */
7723 /* */ 7275 /* */
7724 /*************************************************************************/ 7276 /*************************************************************************/
7725 7277
7726 7278
7727 /*************************************************************************/ 7279 /*************************************************************************/
7728 /* */ 7280 /* */
7729 /* GETINFO[]: GET INFOrmation */ 7281 /* GETINFO[]: GET INFOrmation */
7730 /* Opcode range: 0x88 */ 7282 /* Opcode range: 0x88 */
7731 /* Stack: uint32 --> uint32 */ 7283 /* Stack: uint32 --> uint32 */
7732 /* */ 7284 /* */
7285 /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */
7286 /* 2015) not documented in the OpenType specification. */
7287 /* */
7288 /* Selector bit 11 is incorrectly described as bit 8, while the */
7289 /* real meaning of bit 8 (vertical LCD subpixels) stays */
7290 /* undocumented. The same mistake can be found in Greg Hitchcock's */
7291 /* whitepaper. */
7292 /* */
7733 static void 7293 static void
7734 Ins_GETINFO( INS_ARG ) 7294 Ins_GETINFO( TT_ExecContext exc,
7295 FT_Long* args )
7735 { 7296 {
7736 FT_Long K; 7297 FT_Long K;
7737 7298
7738 7299
7739 K = 0; 7300 K = 0;
7740 7301
7741 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7302 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7742 /********************************/ 7303 /********************************/
7743 /* RASTERIZER VERSION */ 7304 /* RASTERIZER VERSION */
7744 /* Selector Bit: 0 */ 7305 /* Selector Bit: 0 */
7745 /* Return Bit(s): 0-7 */ 7306 /* Return Bit(s): 0-7 */
7746 /* */ 7307 /* */
7747 if ( SUBPIXEL_HINTING && 7308 if ( SUBPIXEL_HINTING &&
7748 ( args[0] & 1 ) != 0 && 7309 ( args[0] & 1 ) != 0 &&
7749 CUR.ignore_x_mode ) 7310 exc->subpixel_hinting )
7750 { 7311 {
7751 K = CUR.rasterizer_version; 7312 if ( exc->ignore_x_mode )
7752 FT_TRACE7(( "Setting rasterizer version %d\n", 7313 {
7753 CUR.rasterizer_version )); 7314 /* if in ClearType backwards compatibility mode, */
7315 /* we sometimes change the TrueType version dynamically */
7316 K = exc->rasterizer_version;
7317 FT_TRACE6(( "Setting rasterizer version %d\n",
7318 exc->rasterizer_version ));
7319 }
7320 else
7321 K = TT_INTERPRETER_VERSION_38;
7754 } 7322 }
7755 else 7323 else
7756 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7324 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
7757 if ( ( args[0] & 1 ) != 0 ) 7325 if ( ( args[0] & 1 ) != 0 )
7758 K = TT_INTERPRETER_VERSION_35; 7326 K = TT_INTERPRETER_VERSION_35;
7759 7327
7760 /********************************/ 7328 /********************************/
7761 /* GLYPH ROTATED */ 7329 /* GLYPH ROTATED */
7762 /* Selector Bit: 1 */ 7330 /* Selector Bit: 1 */
7763 /* Return Bit(s): 8 */ 7331 /* Return Bit(s): 8 */
7764 /* */ 7332 /* */
7765 if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) 7333 if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
7766 K |= 0x80; 7334 K |= 0x80;
7767 7335
7768 /********************************/ 7336 /********************************/
7769 /* GLYPH STRETCHED */ 7337 /* GLYPH STRETCHED */
7770 /* Selector Bit: 2 */ 7338 /* Selector Bit: 2 */
7771 /* Return Bit(s): 9 */ 7339 /* Return Bit(s): 9 */
7772 /* */ 7340 /* */
7773 if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) 7341 if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
7774 K |= 1 << 8; 7342 K |= 1 << 8;
7775 7343
7776 /********************************/ 7344 /********************************/
7777 /* HINTING FOR GRAYSCALE */ 7345 /* HINTING FOR GRAYSCALE */
7778 /* Selector Bit: 5 */ 7346 /* Selector Bit: 5 */
7779 /* Return Bit(s): 12 */ 7347 /* Return Bit(s): 12 */
7780 /* */ 7348 /* */
7781 if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) 7349 if ( ( args[0] & 32 ) != 0 && exc->grayscale )
7782 K |= 1 << 12; 7350 K |= 1 << 12;
7783 7351
7784 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7352 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7785 7353
7786 if ( SUBPIXEL_HINTING && 7354 if ( SUBPIXEL_HINTING &&
7787 CUR.ignore_x_mode && 7355 exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
7788 CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
7789 { 7356 {
7790 7357
7791 if ( CUR.rasterizer_version >= 37 ) 7358 if ( exc->rasterizer_version >= 37 )
7792 { 7359 {
7793 /********************************/ 7360 /********************************/
7794 /* HINTING FOR SUBPIXEL */ 7361 /* HINTING FOR SUBPIXEL */
7795 /* Selector Bit: 6 */ 7362 /* Selector Bit: 6 */
7796 /* Return Bit(s): 13 */ 7363 /* Return Bit(s): 13 */
7797 /* */ 7364 /* */
7798 if ( ( args[0] & 64 ) != 0 && CUR.subpixel ) 7365 if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
7799 K |= 1 << 13; 7366 K |= 1 << 13;
7800 7367
7801 /********************************/ 7368 /********************************/
7802 /* COMPATIBLE WIDTHS ENABLED */ 7369 /* COMPATIBLE WIDTHS ENABLED */
7803 /* Selector Bit: 7 */ 7370 /* Selector Bit: 7 */
7804 /* Return Bit(s): 14 */ 7371 /* Return Bit(s): 14 */
7805 /* */ 7372 /* */
7806 /* Functionality still needs to be added */ 7373 /* Functionality still needs to be added */
7807 if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) 7374 if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
7808 K |= 1 << 14; 7375 K |= 1 << 14;
7809 7376
7810 /********************************/ 7377 /********************************/
7811 /* SYMMETRICAL SMOOTHING */ 7378 /* VERTICAL LCD SUBPIXELS? */
7812 /* Selector Bit: 8 */ 7379 /* Selector Bit: 8 */
7813 /* Return Bit(s): 15 */ 7380 /* Return Bit(s): 15 */
7814 /* */ 7381 /* */
7815 /* Functionality still needs to be added */ 7382 /* Functionality still needs to be added */
7816 if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) 7383 if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
7817 K |= 1 << 15; 7384 K |= 1 << 15;
7818 7385
7819 /********************************/ 7386 /********************************/
7820 /* HINTING FOR BGR? */ 7387 /* HINTING FOR BGR? */
7821 /* Selector Bit: 9 */ 7388 /* Selector Bit: 9 */
7822 /* Return Bit(s): 16 */ 7389 /* Return Bit(s): 16 */
7823 /* */ 7390 /* */
7824 /* Functionality still needs to be added */ 7391 /* Functionality still needs to be added */
7825 if ( ( args[0] & 512 ) != 0 && CUR.bgr ) 7392 if ( ( args[0] & 512 ) != 0 && exc->bgr )
7826 K |= 1 << 16; 7393 K |= 1 << 16;
7827 7394
7828 if ( CUR.rasterizer_version >= 38 ) 7395 if ( exc->rasterizer_version >= 38 )
7829 { 7396 {
7830 /********************************/ 7397 /********************************/
7831 /* SUBPIXEL POSITIONED? */ 7398 /* SUBPIXEL POSITIONED? */
7832 /* Selector Bit: 10 */ 7399 /* Selector Bit: 10 */
7833 /* Return Bit(s): 17 */ 7400 /* Return Bit(s): 17 */
7834 /* */ 7401 /* */
7835 /* Functionality still needs to be added */ 7402 /* Functionality still needs to be added */
7836 if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) 7403 if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
7837 K |= 1 << 17; 7404 K |= 1 << 17;
7405
7406 /********************************/
7407 /* SYMMETRICAL SMOOTHING */
7408 /* Selector Bit: 11 */
7409 /* Return Bit(s): 18 */
7410 /* */
7411 /* Functionality still needs to be added */
7412 if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
7413 K |= 1 << 18;
7414
7415 /********************************/
7416 /* GRAY CLEARTYPE */
7417 /* Selector Bit: 12 */
7418 /* Return Bit(s): 19 */
7419 /* */
7420 /* Functionality still needs to be added */
7421 if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
7422 K |= 1 << 19;
7838 } 7423 }
7839 } 7424 }
7840 } 7425 }
7841 7426
7842 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7427 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
7843 7428
7844 args[0] = K; 7429 args[0] = K;
7845 } 7430 }
7846 7431
7847 7432
7848 static void 7433 static void
7849 Ins_UNKNOWN( INS_ARG ) 7434 Ins_UNKNOWN( TT_ExecContext exc )
7850 { 7435 {
7851 TT_DefRecord* def = CUR.IDefs; 7436 TT_DefRecord* def = exc->IDefs;
7852 TT_DefRecord* limit = def + CUR.numIDefs; 7437 TT_DefRecord* limit = def + exc->numIDefs;
7853
7854 FT_UNUSED_ARG;
7855 7438
7856 7439
7857 for ( ; def < limit; def++ ) 7440 for ( ; def < limit; def++ )
7858 { 7441 {
7859 if ( (FT_Byte)def->opc == CUR.opcode && def->active ) 7442 if ( (FT_Byte)def->opc == exc->opcode && def->active )
7860 { 7443 {
7861 TT_CallRec* call; 7444 TT_CallRec* call;
7862 7445
7863 7446
7864 if ( CUR.callTop >= CUR.callSize ) 7447 if ( exc->callTop >= exc->callSize )
7865 { 7448 {
7866 CUR.error = FT_THROW( Stack_Overflow ); 7449 exc->error = FT_THROW( Stack_Overflow );
7867 return; 7450 return;
7868 } 7451 }
7869 7452
7870 call = CUR.callStack + CUR.callTop++; 7453 call = exc->callStack + exc->callTop++;
7871 7454
7872 call->Caller_Range = CUR.curRange; 7455 call->Caller_Range = exc->curRange;
7873 call->Caller_IP = CUR.IP + 1; 7456 call->Caller_IP = exc->IP + 1;
7874 call->Cur_Count = 1; 7457 call->Cur_Count = 1;
7875 call->Def = def; 7458 call->Def = def;
7876 7459
7877 INS_Goto_CodeRange( def->range, def->start ); 7460 Ins_Goto_CodeRange( exc, def->range, def->start );
7878 7461
7879 CUR.step_ins = FALSE; 7462 exc->step_ins = FALSE;
7880 return; 7463 return;
7881 } 7464 }
7882 } 7465 }
7883 7466
7884 CUR.error = FT_THROW( Invalid_Opcode ); 7467 exc->error = FT_THROW( Invalid_Opcode );
7885 } 7468 }
7886 7469
7887 7470
7888 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
7889
7890
7891 static
7892 TInstruction_Function Instruct_Dispatch[256] =
7893 {
7894 /* Opcodes are gathered in groups of 16. */
7895 /* Please keep the spaces as they are. */
7896
7897 /* SVTCA y */ Ins_SVTCA,
7898 /* SVTCA x */ Ins_SVTCA,
7899 /* SPvTCA y */ Ins_SPVTCA,
7900 /* SPvTCA x */ Ins_SPVTCA,
7901 /* SFvTCA y */ Ins_SFVTCA,
7902 /* SFvTCA x */ Ins_SFVTCA,
7903 /* SPvTL // */ Ins_SPVTL,
7904 /* SPvTL + */ Ins_SPVTL,
7905 /* SFvTL // */ Ins_SFVTL,
7906 /* SFvTL + */ Ins_SFVTL,
7907 /* SPvFS */ Ins_SPVFS,
7908 /* SFvFS */ Ins_SFVFS,
7909 /* GPV */ Ins_GPV,
7910 /* GFV */ Ins_GFV,
7911 /* SFvTPv */ Ins_SFVTPV,
7912 /* ISECT */ Ins_ISECT,
7913
7914 /* SRP0 */ Ins_SRP0,
7915 /* SRP1 */ Ins_SRP1,
7916 /* SRP2 */ Ins_SRP2,
7917 /* SZP0 */ Ins_SZP0,
7918 /* SZP1 */ Ins_SZP1,
7919 /* SZP2 */ Ins_SZP2,
7920 /* SZPS */ Ins_SZPS,
7921 /* SLOOP */ Ins_SLOOP,
7922 /* RTG */ Ins_RTG,
7923 /* RTHG */ Ins_RTHG,
7924 /* SMD */ Ins_SMD,
7925 /* ELSE */ Ins_ELSE,
7926 /* JMPR */ Ins_JMPR,
7927 /* SCvTCi */ Ins_SCVTCI,
7928 /* SSwCi */ Ins_SSWCI,
7929 /* SSW */ Ins_SSW,
7930
7931 /* DUP */ Ins_DUP,
7932 /* POP */ Ins_POP,
7933 /* CLEAR */ Ins_CLEAR,
7934 /* SWAP */ Ins_SWAP,
7935 /* DEPTH */ Ins_DEPTH,
7936 /* CINDEX */ Ins_CINDEX,
7937 /* MINDEX */ Ins_MINDEX,
7938 /* AlignPTS */ Ins_ALIGNPTS,
7939 /* INS_0x28 */ Ins_UNKNOWN,
7940 /* UTP */ Ins_UTP,
7941 /* LOOPCALL */ Ins_LOOPCALL,
7942 /* CALL */ Ins_CALL,
7943 /* FDEF */ Ins_FDEF,
7944 /* ENDF */ Ins_ENDF,
7945 /* MDAP[0] */ Ins_MDAP,
7946 /* MDAP[1] */ Ins_MDAP,
7947
7948 /* IUP[0] */ Ins_IUP,
7949 /* IUP[1] */ Ins_IUP,
7950 /* SHP[0] */ Ins_SHP,
7951 /* SHP[1] */ Ins_SHP,
7952 /* SHC[0] */ Ins_SHC,
7953 /* SHC[1] */ Ins_SHC,
7954 /* SHZ[0] */ Ins_SHZ,
7955 /* SHZ[1] */ Ins_SHZ,
7956 /* SHPIX */ Ins_SHPIX,
7957 /* IP */ Ins_IP,
7958 /* MSIRP[0] */ Ins_MSIRP,
7959 /* MSIRP[1] */ Ins_MSIRP,
7960 /* AlignRP */ Ins_ALIGNRP,
7961 /* RTDG */ Ins_RTDG,
7962 /* MIAP[0] */ Ins_MIAP,
7963 /* MIAP[1] */ Ins_MIAP,
7964
7965 /* NPushB */ Ins_NPUSHB,
7966 /* NPushW */ Ins_NPUSHW,
7967 /* WS */ Ins_WS,
7968 /* RS */ Ins_RS,
7969 /* WCvtP */ Ins_WCVTP,
7970 /* RCvt */ Ins_RCVT,
7971 /* GC[0] */ Ins_GC,
7972 /* GC[1] */ Ins_GC,
7973 /* SCFS */ Ins_SCFS,
7974 /* MD[0] */ Ins_MD,
7975 /* MD[1] */ Ins_MD,
7976 /* MPPEM */ Ins_MPPEM,
7977 /* MPS */ Ins_MPS,
7978 /* FlipON */ Ins_FLIPON,
7979 /* FlipOFF */ Ins_FLIPOFF,
7980 /* DEBUG */ Ins_DEBUG,
7981
7982 /* LT */ Ins_LT,
7983 /* LTEQ */ Ins_LTEQ,
7984 /* GT */ Ins_GT,
7985 /* GTEQ */ Ins_GTEQ,
7986 /* EQ */ Ins_EQ,
7987 /* NEQ */ Ins_NEQ,
7988 /* ODD */ Ins_ODD,
7989 /* EVEN */ Ins_EVEN,
7990 /* IF */ Ins_IF,
7991 /* EIF */ Ins_EIF,
7992 /* AND */ Ins_AND,
7993 /* OR */ Ins_OR,
7994 /* NOT */ Ins_NOT,
7995 /* DeltaP1 */ Ins_DELTAP,
7996 /* SDB */ Ins_SDB,
7997 /* SDS */ Ins_SDS,
7998
7999 /* ADD */ Ins_ADD,
8000 /* SUB */ Ins_SUB,
8001 /* DIV */ Ins_DIV,
8002 /* MUL */ Ins_MUL,
8003 /* ABS */ Ins_ABS,
8004 /* NEG */ Ins_NEG,
8005 /* FLOOR */ Ins_FLOOR,
8006 /* CEILING */ Ins_CEILING,
8007 /* ROUND[0] */ Ins_ROUND,
8008 /* ROUND[1] */ Ins_ROUND,
8009 /* ROUND[2] */ Ins_ROUND,
8010 /* ROUND[3] */ Ins_ROUND,
8011 /* NROUND[0] */ Ins_NROUND,
8012 /* NROUND[1] */ Ins_NROUND,
8013 /* NROUND[2] */ Ins_NROUND,
8014 /* NROUND[3] */ Ins_NROUND,
8015
8016 /* WCvtF */ Ins_WCVTF,
8017 /* DeltaP2 */ Ins_DELTAP,
8018 /* DeltaP3 */ Ins_DELTAP,
8019 /* DeltaCn[0] */ Ins_DELTAC,
8020 /* DeltaCn[1] */ Ins_DELTAC,
8021 /* DeltaCn[2] */ Ins_DELTAC,
8022 /* SROUND */ Ins_SROUND,
8023 /* S45Round */ Ins_S45ROUND,
8024 /* JROT */ Ins_JROT,
8025 /* JROF */ Ins_JROF,
8026 /* ROFF */ Ins_ROFF,
8027 /* INS_0x7B */ Ins_UNKNOWN,
8028 /* RUTG */ Ins_RUTG,
8029 /* RDTG */ Ins_RDTG,
8030 /* SANGW */ Ins_SANGW,
8031 /* AA */ Ins_AA,
8032
8033 /* FlipPT */ Ins_FLIPPT,
8034 /* FlipRgON */ Ins_FLIPRGON,
8035 /* FlipRgOFF */ Ins_FLIPRGOFF,
8036 /* INS_0x83 */ Ins_UNKNOWN,
8037 /* INS_0x84 */ Ins_UNKNOWN,
8038 /* ScanCTRL */ Ins_SCANCTRL,
8039 /* SDPVTL[0] */ Ins_SDPVTL,
8040 /* SDPVTL[1] */ Ins_SDPVTL,
8041 /* GetINFO */ Ins_GETINFO,
8042 /* IDEF */ Ins_IDEF,
8043 /* ROLL */ Ins_ROLL,
8044 /* MAX */ Ins_MAX,
8045 /* MIN */ Ins_MIN,
8046 /* ScanTYPE */ Ins_SCANTYPE,
8047 /* InstCTRL */ Ins_INSTCTRL,
8048 /* INS_0x8F */ Ins_UNKNOWN,
8049
8050 /* INS_0x90 */ Ins_UNKNOWN,
8051 /* INS_0x91 */ Ins_UNKNOWN,
8052 /* INS_0x92 */ Ins_UNKNOWN,
8053 /* INS_0x93 */ Ins_UNKNOWN,
8054 /* INS_0x94 */ Ins_UNKNOWN,
8055 /* INS_0x95 */ Ins_UNKNOWN,
8056 /* INS_0x96 */ Ins_UNKNOWN,
8057 /* INS_0x97 */ Ins_UNKNOWN,
8058 /* INS_0x98 */ Ins_UNKNOWN,
8059 /* INS_0x99 */ Ins_UNKNOWN,
8060 /* INS_0x9A */ Ins_UNKNOWN,
8061 /* INS_0x9B */ Ins_UNKNOWN,
8062 /* INS_0x9C */ Ins_UNKNOWN,
8063 /* INS_0x9D */ Ins_UNKNOWN,
8064 /* INS_0x9E */ Ins_UNKNOWN,
8065 /* INS_0x9F */ Ins_UNKNOWN,
8066
8067 /* INS_0xA0 */ Ins_UNKNOWN,
8068 /* INS_0xA1 */ Ins_UNKNOWN,
8069 /* INS_0xA2 */ Ins_UNKNOWN,
8070 /* INS_0xA3 */ Ins_UNKNOWN,
8071 /* INS_0xA4 */ Ins_UNKNOWN,
8072 /* INS_0xA5 */ Ins_UNKNOWN,
8073 /* INS_0xA6 */ Ins_UNKNOWN,
8074 /* INS_0xA7 */ Ins_UNKNOWN,
8075 /* INS_0xA8 */ Ins_UNKNOWN,
8076 /* INS_0xA9 */ Ins_UNKNOWN,
8077 /* INS_0xAA */ Ins_UNKNOWN,
8078 /* INS_0xAB */ Ins_UNKNOWN,
8079 /* INS_0xAC */ Ins_UNKNOWN,
8080 /* INS_0xAD */ Ins_UNKNOWN,
8081 /* INS_0xAE */ Ins_UNKNOWN,
8082 /* INS_0xAF */ Ins_UNKNOWN,
8083
8084 /* PushB[0] */ Ins_PUSHB,
8085 /* PushB[1] */ Ins_PUSHB,
8086 /* PushB[2] */ Ins_PUSHB,
8087 /* PushB[3] */ Ins_PUSHB,
8088 /* PushB[4] */ Ins_PUSHB,
8089 /* PushB[5] */ Ins_PUSHB,
8090 /* PushB[6] */ Ins_PUSHB,
8091 /* PushB[7] */ Ins_PUSHB,
8092 /* PushW[0] */ Ins_PUSHW,
8093 /* PushW[1] */ Ins_PUSHW,
8094 /* PushW[2] */ Ins_PUSHW,
8095 /* PushW[3] */ Ins_PUSHW,
8096 /* PushW[4] */ Ins_PUSHW,
8097 /* PushW[5] */ Ins_PUSHW,
8098 /* PushW[6] */ Ins_PUSHW,
8099 /* PushW[7] */ Ins_PUSHW,
8100
8101 /* MDRP[00] */ Ins_MDRP,
8102 /* MDRP[01] */ Ins_MDRP,
8103 /* MDRP[02] */ Ins_MDRP,
8104 /* MDRP[03] */ Ins_MDRP,
8105 /* MDRP[04] */ Ins_MDRP,
8106 /* MDRP[05] */ Ins_MDRP,
8107 /* MDRP[06] */ Ins_MDRP,
8108 /* MDRP[07] */ Ins_MDRP,
8109 /* MDRP[08] */ Ins_MDRP,
8110 /* MDRP[09] */ Ins_MDRP,
8111 /* MDRP[10] */ Ins_MDRP,
8112 /* MDRP[11] */ Ins_MDRP,
8113 /* MDRP[12] */ Ins_MDRP,
8114 /* MDRP[13] */ Ins_MDRP,
8115 /* MDRP[14] */ Ins_MDRP,
8116 /* MDRP[15] */ Ins_MDRP,
8117
8118 /* MDRP[16] */ Ins_MDRP,
8119 /* MDRP[17] */ Ins_MDRP,
8120 /* MDRP[18] */ Ins_MDRP,
8121 /* MDRP[19] */ Ins_MDRP,
8122 /* MDRP[20] */ Ins_MDRP,
8123 /* MDRP[21] */ Ins_MDRP,
8124 /* MDRP[22] */ Ins_MDRP,
8125 /* MDRP[23] */ Ins_MDRP,
8126 /* MDRP[24] */ Ins_MDRP,
8127 /* MDRP[25] */ Ins_MDRP,
8128 /* MDRP[26] */ Ins_MDRP,
8129 /* MDRP[27] */ Ins_MDRP,
8130 /* MDRP[28] */ Ins_MDRP,
8131 /* MDRP[29] */ Ins_MDRP,
8132 /* MDRP[30] */ Ins_MDRP,
8133 /* MDRP[31] */ Ins_MDRP,
8134
8135 /* MIRP[00] */ Ins_MIRP,
8136 /* MIRP[01] */ Ins_MIRP,
8137 /* MIRP[02] */ Ins_MIRP,
8138 /* MIRP[03] */ Ins_MIRP,
8139 /* MIRP[04] */ Ins_MIRP,
8140 /* MIRP[05] */ Ins_MIRP,
8141 /* MIRP[06] */ Ins_MIRP,
8142 /* MIRP[07] */ Ins_MIRP,
8143 /* MIRP[08] */ Ins_MIRP,
8144 /* MIRP[09] */ Ins_MIRP,
8145 /* MIRP[10] */ Ins_MIRP,
8146 /* MIRP[11] */ Ins_MIRP,
8147 /* MIRP[12] */ Ins_MIRP,
8148 /* MIRP[13] */ Ins_MIRP,
8149 /* MIRP[14] */ Ins_MIRP,
8150 /* MIRP[15] */ Ins_MIRP,
8151
8152 /* MIRP[16] */ Ins_MIRP,
8153 /* MIRP[17] */ Ins_MIRP,
8154 /* MIRP[18] */ Ins_MIRP,
8155 /* MIRP[19] */ Ins_MIRP,
8156 /* MIRP[20] */ Ins_MIRP,
8157 /* MIRP[21] */ Ins_MIRP,
8158 /* MIRP[22] */ Ins_MIRP,
8159 /* MIRP[23] */ Ins_MIRP,
8160 /* MIRP[24] */ Ins_MIRP,
8161 /* MIRP[25] */ Ins_MIRP,
8162 /* MIRP[26] */ Ins_MIRP,
8163 /* MIRP[27] */ Ins_MIRP,
8164 /* MIRP[28] */ Ins_MIRP,
8165 /* MIRP[29] */ Ins_MIRP,
8166 /* MIRP[30] */ Ins_MIRP,
8167 /* MIRP[31] */ Ins_MIRP
8168 };
8169
8170
8171 #endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
8172
8173
8174 /*************************************************************************/ 7471 /*************************************************************************/
8175 /* */ 7472 /* */
8176 /* RUN */ 7473 /* RUN */
8177 /* */ 7474 /* */
8178 /* This function executes a run of opcodes. It will exit in the */ 7475 /* This function executes a run of opcodes. It will exit in the */
8179 /* following cases: */ 7476 /* following cases: */
8180 /* */ 7477 /* */
8181 /* - Errors (in which case it returns FALSE). */ 7478 /* - Errors (in which case it returns FALSE). */
8182 /* */ 7479 /* */
8183 /* - Reaching the end of the main code range (returns TRUE). */ 7480 /* - Reaching the end of the main code range (returns TRUE). */
8184 /* Reaching the end of a code range within a function call is an */ 7481 /* Reaching the end of a code range within a function call is an */
8185 /* error. */ 7482 /* error. */
8186 /* */ 7483 /* */
8187 /* - After executing one single opcode, if the flag `Instruction_Trap' */ 7484 /* - After executing one single opcode, if the flag `Instruction_Trap' */
8188 /* is set to TRUE (returns TRUE). */ 7485 /* is set to TRUE (returns TRUE). */
8189 /* */ 7486 /* */
8190 /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ 7487 /* On exit with TRUE, test IP < CodeSize to know whether it comes from */
8191 /* an instruction trap or a normal termination. */ 7488 /* an instruction trap or a normal termination. */
8192 /* */ 7489 /* */
8193 /* */ 7490 /* */
8194 /* Note: The documented DEBUG opcode pops a value from the stack. This */ 7491 /* Note: The documented DEBUG opcode pops a value from the stack. This */
8195 /* behaviour is unsupported; here a DEBUG opcode is always an */ 7492 /* behaviour is unsupported; here a DEBUG opcode is always an */
8196 /* error. */ 7493 /* error. */
8197 /* */ 7494 /* */
8198 /* */ 7495 /* */
8199 /* THIS IS THE INTERPRETER'S MAIN LOOP. */ 7496 /* THIS IS THE INTERPRETER'S MAIN LOOP. */
8200 /* */ 7497 /* */
8201 /* Instructions appear in the specification's order. */
8202 /* */
8203 /*************************************************************************/ 7498 /*************************************************************************/
8204 7499
8205 7500
8206 /* documentation is in ttinterp.h */ 7501 /* documentation is in ttinterp.h */
8207 7502
8208 FT_EXPORT_DEF( FT_Error ) 7503 FT_EXPORT_DEF( FT_Error )
8209 TT_RunIns( TT_ExecContext exc ) 7504 TT_RunIns( TT_ExecContext exc )
8210 { 7505 {
8211 FT_Long ins_counter = 0; /* executed instructions counter */ 7506 FT_Long ins_counter = 0; /* executed instructions counter */
8212 FT_UShort i; 7507 FT_UShort i;
8213 7508
8214 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7509 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
8215 FT_Byte opcode_pattern[1][2] = { 7510 FT_Byte opcode_pattern[1][2] = {
8216 /* #8 TypeMan Talk Align */ 7511 /* #8 TypeMan Talk Align */
8217 { 7512 {
8218 0x06, /* SPVTL */ 7513 0x06, /* SPVTL */
8219 0x7D, /* RDTG */ 7514 0x7D, /* RDTG */
8220 }, 7515 },
8221 }; 7516 };
8222 FT_UShort opcode_patterns = 1; 7517 FT_UShort opcode_patterns = 1;
8223 FT_UShort opcode_pointer[1] = { 0 }; 7518 FT_UShort opcode_pointer[1] = { 0 };
8224 FT_UShort opcode_size[1] = { 1 }; 7519 FT_UShort opcode_size[1] = { 1 };
8225 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7520 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
8226 7521
8227 7522
8228 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
8229 if ( !exc )
8230 return FT_THROW( Invalid_Argument );
8231
8232 cur = *exc;
8233 #endif
8234
8235 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7523 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
8236 CUR.iup_called = FALSE; 7524 exc->iup_called = FALSE;
8237 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7525 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
8238 7526
8239 /* set PPEM and CVT functions */ 7527 /* set PPEM and CVT functions */
8240 CUR.tt_metrics.ratio = 0; 7528 exc->tt_metrics.ratio = 0;
8241 if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) 7529 if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
8242 { 7530 {
8243 /* non-square pixels, use the stretched routines */ 7531 /* non-square pixels, use the stretched routines */
8244 CUR.func_cur_ppem = Current_Ppem_Stretched; 7532 exc->func_cur_ppem = Current_Ppem_Stretched;
8245 CUR.func_read_cvt = Read_CVT_Stretched; 7533 exc->func_read_cvt = Read_CVT_Stretched;
8246 CUR.func_write_cvt = Write_CVT_Stretched; 7534 exc->func_write_cvt = Write_CVT_Stretched;
8247 CUR.func_move_cvt = Move_CVT_Stretched; 7535 exc->func_move_cvt = Move_CVT_Stretched;
8248 } 7536 }
8249 else 7537 else
8250 { 7538 {
8251 /* square pixels, use normal routines */ 7539 /* square pixels, use normal routines */
8252 CUR.func_cur_ppem = Current_Ppem; 7540 exc->func_cur_ppem = Current_Ppem;
8253 CUR.func_read_cvt = Read_CVT; 7541 exc->func_read_cvt = Read_CVT;
8254 CUR.func_write_cvt = Write_CVT; 7542 exc->func_write_cvt = Write_CVT;
8255 CUR.func_move_cvt = Move_CVT; 7543 exc->func_move_cvt = Move_CVT;
8256 } 7544 }
8257 7545
8258 COMPUTE_Funcs(); 7546 Compute_Funcs( exc );
8259 COMPUTE_Round( (FT_Byte)exc->GS.round_state ); 7547 Compute_Round( exc, (FT_Byte)exc->GS.round_state );
8260 7548
8261 do 7549 do
8262 { 7550 {
8263 CUR.opcode = CUR.code[CUR.IP]; 7551 exc->opcode = exc->code[exc->IP];
8264 7552
8265 FT_TRACE7(( " " )); 7553 #ifdef FT_DEBUG_LEVEL_TRACE
8266 FT_TRACE7(( opcode_name[CUR.opcode] )); 7554 {
8267 FT_TRACE7(( "\n" )); 7555 FT_Long cnt = FT_MIN( 8, exc->top );
7556 FT_Long n;
8268 7557
8269 if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) 7558
7559 /* if tracing level is 7, show current code position */
7560 /* and the first few stack elements also */
7561 FT_TRACE6(( " " ));
7562 FT_TRACE7(( "%06d ", exc->IP ));
7563 FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
7564 FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
7565 ? 2
7566 : 12 - ( *opcode_name[exc->opcode] - '0' ),
7567 "#" ));
7568 for ( n = 0; n < cnt; n++ )
7569 FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
7570 FT_TRACE6(( "\n" ));
7571 }
7572 #endif /* FT_DEBUG_LEVEL_TRACE */
7573
7574 if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
8270 { 7575 {
8271 if ( CUR.IP + 1 >= CUR.codeSize ) 7576 if ( exc->IP + 1 >= exc->codeSize )
8272 goto LErrorCodeOverflow_; 7577 goto LErrorCodeOverflow_;
8273 7578
8274 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; 7579 exc->length = 2 - exc->length * exc->code[exc->IP + 1];
8275 } 7580 }
8276 7581
8277 if ( CUR.IP + CUR.length > CUR.codeSize ) 7582 if ( exc->IP + exc->length > exc->codeSize )
8278 goto LErrorCodeOverflow_; 7583 goto LErrorCodeOverflow_;
8279 7584
8280 /* First, let's check for empty stack and overflow */ 7585 /* First, let's check for empty stack and overflow */
8281 CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); 7586 exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
8282 7587
8283 /* `args' is the top of the stack once arguments have been popped. */ 7588 /* `args' is the top of the stack once arguments have been popped. */
8284 /* One can also interpret it as the index of the last argument. */ 7589 /* One can also interpret it as the index of the last argument. */
8285 if ( CUR.args < 0 ) 7590 if ( exc->args < 0 )
8286 { 7591 {
8287 if ( CUR.pedantic_hinting ) 7592 if ( exc->pedantic_hinting )
8288 { 7593 {
8289 CUR.error = FT_THROW( Too_Few_Arguments ); 7594 exc->error = FT_THROW( Too_Few_Arguments );
8290 goto LErrorLabel_; 7595 goto LErrorLabel_;
8291 } 7596 }
8292 7597
8293 /* push zeroes onto the stack */ 7598 /* push zeroes onto the stack */
8294 for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) 7599 for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
8295 CUR.stack[i] = 0; 7600 exc->stack[i] = 0;
8296 CUR.args = 0; 7601 exc->args = 0;
8297 } 7602 }
8298 7603
8299 CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); 7604 exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
8300 7605
8301 /* `new_top' is the new top of the stack, after the instruction's */ 7606 /* `new_top' is the new top of the stack, after the instruction's */
8302 /* execution. `top' will be set to `new_top' after the `switch' */ 7607 /* execution. `top' will be set to `new_top' after the `switch' */
8303 /* statement. */ 7608 /* statement. */
8304 if ( CUR.new_top > CUR.stackSize ) 7609 if ( exc->new_top > exc->stackSize )
8305 { 7610 {
8306 CUR.error = FT_THROW( Stack_Overflow ); 7611 exc->error = FT_THROW( Stack_Overflow );
8307 goto LErrorLabel_; 7612 goto LErrorLabel_;
8308 } 7613 }
8309 7614
8310 CUR.step_ins = TRUE; 7615 exc->step_ins = TRUE;
8311 CUR.error = FT_Err_Ok; 7616 exc->error = FT_Err_Ok;
8312 7617
8313 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7618 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
8314 7619
8315 if ( SUBPIXEL_HINTING ) 7620 if ( SUBPIXEL_HINTING )
8316 { 7621 {
8317 for ( i = 0; i < opcode_patterns; i++ ) 7622 for ( i = 0; i < opcode_patterns; i++ )
8318 { 7623 {
8319 if ( opcode_pointer[i] < opcode_size[i] && 7624 if ( opcode_pointer[i] < opcode_size[i] &&
8320 CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) 7625 exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
8321 { 7626 {
8322 opcode_pointer[i] += 1; 7627 opcode_pointer[i] += 1;
8323 7628
8324 if ( opcode_pointer[i] == opcode_size[i] ) 7629 if ( opcode_pointer[i] == opcode_size[i] )
8325 { 7630 {
8326 FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", 7631 FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
8327 i, 7632 i,
8328 CUR.face->root.family_name, 7633 exc->face->root.family_name,
8329 CUR.face->root.style_name )); 7634 exc->face->root.style_name ));
8330 7635
8331 switch ( i ) 7636 switch ( i )
8332 { 7637 {
8333 case 0: 7638 case 0:
8334 break; 7639 break;
8335 } 7640 }
8336 opcode_pointer[i] = 0; 7641 opcode_pointer[i] = 0;
8337 } 7642 }
8338 } 7643 }
8339 else 7644 else
8340 opcode_pointer[i] = 0; 7645 opcode_pointer[i] = 0;
8341 } 7646 }
8342 } 7647 }
8343 7648
8344 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 7649 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
8345 7650
8346 #ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
8347
8348 { 7651 {
8349 FT_Long* args = CUR.stack + CUR.args; 7652 FT_Long* args = exc->stack + exc->args;
8350 FT_Byte opcode = CUR.opcode; 7653 FT_Byte opcode = exc->opcode;
8351
8352
8353 #undef ARRAY_BOUND_ERROR
8354 #define ARRAY_BOUND_ERROR goto Set_Invalid_Ref
8355 7654
8356 7655
8357 switch ( opcode ) 7656 switch ( opcode )
8358 { 7657 {
8359 case 0x00: /* SVTCA y */ 7658 case 0x00: /* SVTCA y */
8360 case 0x01: /* SVTCA x */ 7659 case 0x01: /* SVTCA x */
8361 case 0x02: /* SPvTCA y */ 7660 case 0x02: /* SPvTCA y */
8362 case 0x03: /* SPvTCA x */ 7661 case 0x03: /* SPvTCA x */
8363 case 0x04: /* SFvTCA y */ 7662 case 0x04: /* SFvTCA y */
8364 case 0x05: /* SFvTCA x */ 7663 case 0x05: /* SFvTCA x */
8365 { 7664 Ins_SxyTCA( exc );
8366 FT_Short AA, BB;
8367
8368
8369 AA = (FT_Short)( ( opcode & 1 ) << 14 );
8370 BB = (FT_Short)( AA ^ 0x4000 );
8371
8372 if ( opcode < 4 )
8373 {
8374 CUR.GS.projVector.x = AA;
8375 CUR.GS.projVector.y = BB;
8376
8377 CUR.GS.dualVector.x = AA;
8378 CUR.GS.dualVector.y = BB;
8379 }
8380 else
8381 {
8382 GUESS_VECTOR( projVector );
8383 }
8384
8385 if ( ( opcode & 2 ) == 0 )
8386 {
8387 CUR.GS.freeVector.x = AA;
8388 CUR.GS.freeVector.y = BB;
8389 }
8390 else
8391 {
8392 GUESS_VECTOR( freeVector );
8393 }
8394
8395 COMPUTE_Funcs();
8396 }
8397 break; 7665 break;
8398 7666
8399 case 0x06: /* SPvTL // */ 7667 case 0x06: /* SPvTL // */
8400 case 0x07: /* SPvTL + */ 7668 case 0x07: /* SPvTL + */
8401 DO_SPVTL 7669 Ins_SPVTL( exc, args );
8402 break; 7670 break;
8403 7671
8404 case 0x08: /* SFvTL // */ 7672 case 0x08: /* SFvTL // */
8405 case 0x09: /* SFvTL + */ 7673 case 0x09: /* SFvTL + */
8406 DO_SFVTL 7674 Ins_SFVTL( exc, args );
8407 break; 7675 break;
8408 7676
8409 case 0x0A: /* SPvFS */ 7677 case 0x0A: /* SPvFS */
8410 DO_SPVFS 7678 Ins_SPVFS( exc, args );
8411 break; 7679 break;
8412 7680
8413 case 0x0B: /* SFvFS */ 7681 case 0x0B: /* SFvFS */
8414 DO_SFVFS 7682 Ins_SFVFS( exc, args );
8415 break; 7683 break;
8416 7684
8417 case 0x0C: /* GPV */ 7685 case 0x0C: /* GPv */
8418 DO_GPV 7686 Ins_GPV( exc, args );
8419 break; 7687 break;
8420 7688
8421 case 0x0D: /* GFV */ 7689 case 0x0D: /* GFv */
8422 DO_GFV 7690 Ins_GFV( exc, args );
8423 break; 7691 break;
8424 7692
8425 case 0x0E: /* SFvTPv */ 7693 case 0x0E: /* SFvTPv */
8426 DO_SFVTPV 7694 Ins_SFVTPV( exc );
8427 break; 7695 break;
8428 7696
8429 case 0x0F: /* ISECT */ 7697 case 0x0F: /* ISECT */
8430 Ins_ISECT( EXEC_ARG_ args ); 7698 Ins_ISECT( exc, args );
8431 break; 7699 break;
8432 7700
8433 case 0x10: /* SRP0 */ 7701 case 0x10: /* SRP0 */
8434 DO_SRP0 7702 Ins_SRP0( exc, args );
8435 break; 7703 break;
8436 7704
8437 case 0x11: /* SRP1 */ 7705 case 0x11: /* SRP1 */
8438 DO_SRP1 7706 Ins_SRP1( exc, args );
8439 break; 7707 break;
8440 7708
8441 case 0x12: /* SRP2 */ 7709 case 0x12: /* SRP2 */
8442 DO_SRP2 7710 Ins_SRP2( exc, args );
8443 break; 7711 break;
8444 7712
8445 case 0x13: /* SZP0 */ 7713 case 0x13: /* SZP0 */
8446 Ins_SZP0( EXEC_ARG_ args ); 7714 Ins_SZP0( exc, args );
8447 break; 7715 break;
8448 7716
8449 case 0x14: /* SZP1 */ 7717 case 0x14: /* SZP1 */
8450 Ins_SZP1( EXEC_ARG_ args ); 7718 Ins_SZP1( exc, args );
8451 break; 7719 break;
8452 7720
8453 case 0x15: /* SZP2 */ 7721 case 0x15: /* SZP2 */
8454 Ins_SZP2( EXEC_ARG_ args ); 7722 Ins_SZP2( exc, args );
8455 break; 7723 break;
8456 7724
8457 case 0x16: /* SZPS */ 7725 case 0x16: /* SZPS */
8458 Ins_SZPS( EXEC_ARG_ args ); 7726 Ins_SZPS( exc, args );
8459 break; 7727 break;
8460 7728
8461 case 0x17: /* SLOOP */ 7729 case 0x17: /* SLOOP */
8462 DO_SLOOP 7730 Ins_SLOOP( exc, args );
8463 break; 7731 break;
8464 7732
8465 case 0x18: /* RTG */ 7733 case 0x18: /* RTG */
8466 DO_RTG 7734 Ins_RTG( exc );
8467 break; 7735 break;
8468 7736
8469 case 0x19: /* RTHG */ 7737 case 0x19: /* RTHG */
8470 DO_RTHG 7738 Ins_RTHG( exc );
8471 break; 7739 break;
8472 7740
8473 case 0x1A: /* SMD */ 7741 case 0x1A: /* SMD */
8474 DO_SMD 7742 Ins_SMD( exc, args );
8475 break; 7743 break;
8476 7744
8477 case 0x1B: /* ELSE */ 7745 case 0x1B: /* ELSE */
8478 Ins_ELSE( EXEC_ARG_ args ); 7746 Ins_ELSE( exc );
8479 break; 7747 break;
8480 7748
8481 case 0x1C: /* JMPR */ 7749 case 0x1C: /* JMPR */
8482 DO_JMPR 7750 Ins_JMPR( exc, args );
8483 break; 7751 break;
8484 7752
8485 case 0x1D: /* SCVTCI */ 7753 case 0x1D: /* SCVTCI */
8486 DO_SCVTCI 7754 Ins_SCVTCI( exc, args );
8487 break; 7755 break;
8488 7756
8489 case 0x1E: /* SSWCI */ 7757 case 0x1E: /* SSWCI */
8490 DO_SSWCI 7758 Ins_SSWCI( exc, args );
8491 break; 7759 break;
8492 7760
8493 case 0x1F: /* SSW */ 7761 case 0x1F: /* SSW */
8494 DO_SSW 7762 Ins_SSW( exc, args );
8495 break; 7763 break;
8496 7764
8497 case 0x20: /* DUP */ 7765 case 0x20: /* DUP */
8498 DO_DUP 7766 Ins_DUP( args );
8499 break; 7767 break;
8500 7768
8501 case 0x21: /* POP */ 7769 case 0x21: /* POP */
8502 /* nothing :-) */ 7770 Ins_POP();
8503 break; 7771 break;
8504 7772
8505 case 0x22: /* CLEAR */ 7773 case 0x22: /* CLEAR */
8506 DO_CLEAR 7774 Ins_CLEAR( exc );
8507 break; 7775 break;
8508 7776
8509 case 0x23: /* SWAP */ 7777 case 0x23: /* SWAP */
8510 DO_SWAP 7778 Ins_SWAP( args );
8511 break; 7779 break;
8512 7780
8513 case 0x24: /* DEPTH */ 7781 case 0x24: /* DEPTH */
8514 DO_DEPTH 7782 Ins_DEPTH( exc, args );
8515 break; 7783 break;
8516 7784
8517 case 0x25: /* CINDEX */ 7785 case 0x25: /* CINDEX */
8518 DO_CINDEX 7786 Ins_CINDEX( exc, args );
8519 break; 7787 break;
8520 7788
8521 case 0x26: /* MINDEX */ 7789 case 0x26: /* MINDEX */
8522 Ins_MINDEX( EXEC_ARG_ args ); 7790 Ins_MINDEX( exc, args );
8523 break; 7791 break;
8524 7792
8525 case 0x27: /* ALIGNPTS */ 7793 case 0x27: /* ALIGNPTS */
8526 Ins_ALIGNPTS( EXEC_ARG_ args ); 7794 Ins_ALIGNPTS( exc, args );
8527 break; 7795 break;
8528 7796
8529 case 0x28: /* ???? */ 7797 case 0x28: /* ???? */
8530 Ins_UNKNOWN( EXEC_ARG_ args ); 7798 Ins_UNKNOWN( exc );
8531 break; 7799 break;
8532 7800
8533 case 0x29: /* UTP */ 7801 case 0x29: /* UTP */
8534 Ins_UTP( EXEC_ARG_ args ); 7802 Ins_UTP( exc, args );
8535 break; 7803 break;
8536 7804
8537 case 0x2A: /* LOOPCALL */ 7805 case 0x2A: /* LOOPCALL */
8538 Ins_LOOPCALL( EXEC_ARG_ args ); 7806 Ins_LOOPCALL( exc, args );
8539 break; 7807 break;
8540 7808
8541 case 0x2B: /* CALL */ 7809 case 0x2B: /* CALL */
8542 Ins_CALL( EXEC_ARG_ args ); 7810 Ins_CALL( exc, args );
8543 break; 7811 break;
8544 7812
8545 case 0x2C: /* FDEF */ 7813 case 0x2C: /* FDEF */
8546 Ins_FDEF( EXEC_ARG_ args ); 7814 Ins_FDEF( exc, args );
8547 break; 7815 break;
8548 7816
8549 case 0x2D: /* ENDF */ 7817 case 0x2D: /* ENDF */
8550 Ins_ENDF( EXEC_ARG_ args ); 7818 Ins_ENDF( exc );
8551 break; 7819 break;
8552 7820
8553 case 0x2E: /* MDAP */ 7821 case 0x2E: /* MDAP */
8554 case 0x2F: /* MDAP */ 7822 case 0x2F: /* MDAP */
8555 Ins_MDAP( EXEC_ARG_ args ); 7823 Ins_MDAP( exc, args );
8556 break; 7824 break;
8557 7825
8558 case 0x30: /* IUP */ 7826 case 0x30: /* IUP */
8559 case 0x31: /* IUP */ 7827 case 0x31: /* IUP */
8560 Ins_IUP( EXEC_ARG_ args ); 7828 Ins_IUP( exc );
8561 break; 7829 break;
8562 7830
8563 case 0x32: /* SHP */ 7831 case 0x32: /* SHP */
8564 case 0x33: /* SHP */ 7832 case 0x33: /* SHP */
8565 Ins_SHP( EXEC_ARG_ args ); 7833 Ins_SHP( exc );
8566 break; 7834 break;
8567 7835
8568 case 0x34: /* SHC */ 7836 case 0x34: /* SHC */
8569 case 0x35: /* SHC */ 7837 case 0x35: /* SHC */
8570 Ins_SHC( EXEC_ARG_ args ); 7838 Ins_SHC( exc, args );
8571 break; 7839 break;
8572 7840
8573 case 0x36: /* SHZ */ 7841 case 0x36: /* SHZ */
8574 case 0x37: /* SHZ */ 7842 case 0x37: /* SHZ */
8575 Ins_SHZ( EXEC_ARG_ args ); 7843 Ins_SHZ( exc, args );
8576 break; 7844 break;
8577 7845
8578 case 0x38: /* SHPIX */ 7846 case 0x38: /* SHPIX */
8579 Ins_SHPIX( EXEC_ARG_ args ); 7847 Ins_SHPIX( exc, args );
8580 break; 7848 break;
8581 7849
8582 case 0x39: /* IP */ 7850 case 0x39: /* IP */
8583 Ins_IP( EXEC_ARG_ args ); 7851 Ins_IP( exc );
8584 break; 7852 break;
8585 7853
8586 case 0x3A: /* MSIRP */ 7854 case 0x3A: /* MSIRP */
8587 case 0x3B: /* MSIRP */ 7855 case 0x3B: /* MSIRP */
8588 Ins_MSIRP( EXEC_ARG_ args ); 7856 Ins_MSIRP( exc, args );
8589 break; 7857 break;
8590 7858
8591 case 0x3C: /* AlignRP */ 7859 case 0x3C: /* AlignRP */
8592 Ins_ALIGNRP( EXEC_ARG_ args ); 7860 Ins_ALIGNRP( exc );
8593 break; 7861 break;
8594 7862
8595 case 0x3D: /* RTDG */ 7863 case 0x3D: /* RTDG */
8596 DO_RTDG 7864 Ins_RTDG( exc );
8597 break; 7865 break;
8598 7866
8599 case 0x3E: /* MIAP */ 7867 case 0x3E: /* MIAP */
8600 case 0x3F: /* MIAP */ 7868 case 0x3F: /* MIAP */
8601 Ins_MIAP( EXEC_ARG_ args ); 7869 Ins_MIAP( exc, args );
8602 break; 7870 break;
8603 7871
8604 case 0x40: /* NPUSHB */ 7872 case 0x40: /* NPUSHB */
8605 Ins_NPUSHB( EXEC_ARG_ args ); 7873 Ins_NPUSHB( exc, args );
8606 break; 7874 break;
8607 7875
8608 case 0x41: /* NPUSHW */ 7876 case 0x41: /* NPUSHW */
8609 Ins_NPUSHW( EXEC_ARG_ args ); 7877 Ins_NPUSHW( exc, args );
8610 break; 7878 break;
8611 7879
8612 case 0x42: /* WS */ 7880 case 0x42: /* WS */
8613 DO_WS 7881 Ins_WS( exc, args );
8614 break;
8615
8616 Set_Invalid_Ref:
8617 CUR.error = FT_THROW( Invalid_Reference );
8618 break; 7882 break;
8619 7883
8620 case 0x43: /* RS */ 7884 case 0x43: /* RS */
8621 DO_RS 7885 Ins_RS( exc, args );
8622 break; 7886 break;
8623 7887
8624 case 0x44: /* WCVTP */ 7888 case 0x44: /* WCVTP */
8625 DO_WCVTP 7889 Ins_WCVTP( exc, args );
8626 break; 7890 break;
8627 7891
8628 case 0x45: /* RCVT */ 7892 case 0x45: /* RCVT */
8629 DO_RCVT 7893 Ins_RCVT( exc, args );
8630 break; 7894 break;
8631 7895
8632 case 0x46: /* GC */ 7896 case 0x46: /* GC */
8633 case 0x47: /* GC */ 7897 case 0x47: /* GC */
8634 Ins_GC( EXEC_ARG_ args ); 7898 Ins_GC( exc, args );
8635 break; 7899 break;
8636 7900
8637 case 0x48: /* SCFS */ 7901 case 0x48: /* SCFS */
8638 Ins_SCFS( EXEC_ARG_ args ); 7902 Ins_SCFS( exc, args );
8639 break; 7903 break;
8640 7904
8641 case 0x49: /* MD */ 7905 case 0x49: /* MD */
8642 case 0x4A: /* MD */ 7906 case 0x4A: /* MD */
8643 Ins_MD( EXEC_ARG_ args ); 7907 Ins_MD( exc, args );
8644 break; 7908 break;
8645 7909
8646 case 0x4B: /* MPPEM */ 7910 case 0x4B: /* MPPEM */
8647 DO_MPPEM 7911 Ins_MPPEM( exc, args );
8648 break; 7912 break;
8649 7913
8650 case 0x4C: /* MPS */ 7914 case 0x4C: /* MPS */
8651 DO_MPS 7915 Ins_MPS( exc, args );
8652 break; 7916 break;
8653 7917
8654 case 0x4D: /* FLIPON */ 7918 case 0x4D: /* FLIPON */
8655 DO_FLIPON 7919 Ins_FLIPON( exc );
8656 break; 7920 break;
8657 7921
8658 case 0x4E: /* FLIPOFF */ 7922 case 0x4E: /* FLIPOFF */
8659 DO_FLIPOFF 7923 Ins_FLIPOFF( exc );
8660 break; 7924 break;
8661 7925
8662 case 0x4F: /* DEBUG */ 7926 case 0x4F: /* DEBUG */
8663 DO_DEBUG 7927 Ins_DEBUG( exc );
8664 break; 7928 break;
8665 7929
8666 case 0x50: /* LT */ 7930 case 0x50: /* LT */
8667 DO_LT 7931 Ins_LT( args );
8668 break; 7932 break;
8669 7933
8670 case 0x51: /* LTEQ */ 7934 case 0x51: /* LTEQ */
8671 DO_LTEQ 7935 Ins_LTEQ( args );
8672 break; 7936 break;
8673 7937
8674 case 0x52: /* GT */ 7938 case 0x52: /* GT */
8675 DO_GT 7939 Ins_GT( args );
8676 break; 7940 break;
8677 7941
8678 case 0x53: /* GTEQ */ 7942 case 0x53: /* GTEQ */
8679 DO_GTEQ 7943 Ins_GTEQ( args );
8680 break; 7944 break;
8681 7945
8682 case 0x54: /* EQ */ 7946 case 0x54: /* EQ */
8683 DO_EQ 7947 Ins_EQ( args );
8684 break; 7948 break;
8685 7949
8686 case 0x55: /* NEQ */ 7950 case 0x55: /* NEQ */
8687 DO_NEQ 7951 Ins_NEQ( args );
8688 break; 7952 break;
8689 7953
8690 case 0x56: /* ODD */ 7954 case 0x56: /* ODD */
8691 DO_ODD 7955 Ins_ODD( exc, args );
8692 break; 7956 break;
8693 7957
8694 case 0x57: /* EVEN */ 7958 case 0x57: /* EVEN */
8695 DO_EVEN 7959 Ins_EVEN( exc, args );
8696 break; 7960 break;
8697 7961
8698 case 0x58: /* IF */ 7962 case 0x58: /* IF */
8699 Ins_IF( EXEC_ARG_ args ); 7963 Ins_IF( exc, args );
8700 break; 7964 break;
8701 7965
8702 case 0x59: /* EIF */ 7966 case 0x59: /* EIF */
8703 /* do nothing */ 7967 Ins_EIF();
8704 break; 7968 break;
8705 7969
8706 case 0x5A: /* AND */ 7970 case 0x5A: /* AND */
8707 DO_AND 7971 Ins_AND( args );
8708 break; 7972 break;
8709 7973
8710 case 0x5B: /* OR */ 7974 case 0x5B: /* OR */
8711 DO_OR 7975 Ins_OR( args );
8712 break; 7976 break;
8713 7977
8714 case 0x5C: /* NOT */ 7978 case 0x5C: /* NOT */
8715 DO_NOT 7979 Ins_NOT( args );
8716 break; 7980 break;
8717 7981
8718 case 0x5D: /* DELTAP1 */ 7982 case 0x5D: /* DELTAP1 */
8719 Ins_DELTAP( EXEC_ARG_ args ); 7983 Ins_DELTAP( exc, args );
8720 break; 7984 break;
8721 7985
8722 case 0x5E: /* SDB */ 7986 case 0x5E: /* SDB */
8723 DO_SDB 7987 Ins_SDB( exc, args );
8724 break; 7988 break;
8725 7989
8726 case 0x5F: /* SDS */ 7990 case 0x5F: /* SDS */
8727 DO_SDS 7991 Ins_SDS( exc, args );
8728 break; 7992 break;
8729 7993
8730 case 0x60: /* ADD */ 7994 case 0x60: /* ADD */
8731 DO_ADD 7995 Ins_ADD( args );
8732 break; 7996 break;
8733 7997
8734 case 0x61: /* SUB */ 7998 case 0x61: /* SUB */
8735 DO_SUB 7999 Ins_SUB( args );
8736 break; 8000 break;
8737 8001
8738 case 0x62: /* DIV */ 8002 case 0x62: /* DIV */
8739 DO_DIV 8003 Ins_DIV( exc, args );
8740 break; 8004 break;
8741 8005
8742 case 0x63: /* MUL */ 8006 case 0x63: /* MUL */
8743 DO_MUL 8007 Ins_MUL( args );
8744 break; 8008 break;
8745 8009
8746 case 0x64: /* ABS */ 8010 case 0x64: /* ABS */
8747 DO_ABS 8011 Ins_ABS( args );
8748 break; 8012 break;
8749 8013
8750 case 0x65: /* NEG */ 8014 case 0x65: /* NEG */
8751 DO_NEG 8015 Ins_NEG( args );
8752 break; 8016 break;
8753 8017
8754 case 0x66: /* FLOOR */ 8018 case 0x66: /* FLOOR */
8755 DO_FLOOR 8019 Ins_FLOOR( args );
8756 break; 8020 break;
8757 8021
8758 case 0x67: /* CEILING */ 8022 case 0x67: /* CEILING */
8759 DO_CEILING 8023 Ins_CEILING( args );
8760 break; 8024 break;
8761 8025
8762 case 0x68: /* ROUND */ 8026 case 0x68: /* ROUND */
8763 case 0x69: /* ROUND */ 8027 case 0x69: /* ROUND */
8764 case 0x6A: /* ROUND */ 8028 case 0x6A: /* ROUND */
8765 case 0x6B: /* ROUND */ 8029 case 0x6B: /* ROUND */
8766 DO_ROUND 8030 Ins_ROUND( exc, args );
8767 break; 8031 break;
8768 8032
8769 case 0x6C: /* NROUND */ 8033 case 0x6C: /* NROUND */
8770 case 0x6D: /* NROUND */ 8034 case 0x6D: /* NROUND */
8771 case 0x6E: /* NRRUND */ 8035 case 0x6E: /* NRRUND */
8772 case 0x6F: /* NROUND */ 8036 case 0x6F: /* NROUND */
8773 DO_NROUND 8037 Ins_NROUND( exc, args );
8774 break; 8038 break;
8775 8039
8776 case 0x70: /* WCVTF */ 8040 case 0x70: /* WCVTF */
8777 DO_WCVTF 8041 Ins_WCVTF( exc, args );
8778 break; 8042 break;
8779 8043
8780 case 0x71: /* DELTAP2 */ 8044 case 0x71: /* DELTAP2 */
8781 case 0x72: /* DELTAP3 */ 8045 case 0x72: /* DELTAP3 */
8782 Ins_DELTAP( EXEC_ARG_ args ); 8046 Ins_DELTAP( exc, args );
8783 break; 8047 break;
8784 8048
8785 case 0x73: /* DELTAC0 */ 8049 case 0x73: /* DELTAC0 */
8786 case 0x74: /* DELTAC1 */ 8050 case 0x74: /* DELTAC1 */
8787 case 0x75: /* DELTAC2 */ 8051 case 0x75: /* DELTAC2 */
8788 Ins_DELTAC( EXEC_ARG_ args ); 8052 Ins_DELTAC( exc, args );
8789 break; 8053 break;
8790 8054
8791 case 0x76: /* SROUND */ 8055 case 0x76: /* SROUND */
8792 DO_SROUND 8056 Ins_SROUND( exc, args );
8793 break; 8057 break;
8794 8058
8795 case 0x77: /* S45Round */ 8059 case 0x77: /* S45Round */
8796 DO_S45ROUND 8060 Ins_S45ROUND( exc, args );
8797 break; 8061 break;
8798 8062
8799 case 0x78: /* JROT */ 8063 case 0x78: /* JROT */
8800 DO_JROT 8064 Ins_JROT( exc, args );
8801 break; 8065 break;
8802 8066
8803 case 0x79: /* JROF */ 8067 case 0x79: /* JROF */
8804 DO_JROF 8068 Ins_JROF( exc, args );
8805 break; 8069 break;
8806 8070
8807 case 0x7A: /* ROFF */ 8071 case 0x7A: /* ROFF */
8808 DO_ROFF 8072 Ins_ROFF( exc );
8809 break; 8073 break;
8810 8074
8811 case 0x7B: /* ???? */ 8075 case 0x7B: /* ???? */
8812 Ins_UNKNOWN( EXEC_ARG_ args ); 8076 Ins_UNKNOWN( exc );
8813 break; 8077 break;
8814 8078
8815 case 0x7C: /* RUTG */ 8079 case 0x7C: /* RUTG */
8816 DO_RUTG 8080 Ins_RUTG( exc );
8817 break; 8081 break;
8818 8082
8819 case 0x7D: /* RDTG */ 8083 case 0x7D: /* RDTG */
8820 DO_RDTG 8084 Ins_RDTG( exc );
8821 break; 8085 break;
8822 8086
8823 case 0x7E: /* SANGW */ 8087 case 0x7E: /* SANGW */
8824 case 0x7F: /* AA */ 8088 Ins_SANGW();
8825 /* nothing - obsolete */ 8089 break;
8090
8091 case 0x7F: /* AA */
8092 Ins_AA();
8826 break; 8093 break;
8827 8094
8828 case 0x80: /* FLIPPT */ 8095 case 0x80: /* FLIPPT */
8829 Ins_FLIPPT( EXEC_ARG_ args ); 8096 Ins_FLIPPT( exc );
8830 break; 8097 break;
8831 8098
8832 case 0x81: /* FLIPRGON */ 8099 case 0x81: /* FLIPRGON */
8833 Ins_FLIPRGON( EXEC_ARG_ args ); 8100 Ins_FLIPRGON( exc, args );
8834 break; 8101 break;
8835 8102
8836 case 0x82: /* FLIPRGOFF */ 8103 case 0x82: /* FLIPRGOFF */
8837 Ins_FLIPRGOFF( EXEC_ARG_ args ); 8104 Ins_FLIPRGOFF( exc, args );
8838 break; 8105 break;
8839 8106
8840 case 0x83: /* UNKNOWN */ 8107 case 0x83: /* UNKNOWN */
8841 case 0x84: /* UNKNOWN */ 8108 case 0x84: /* UNKNOWN */
8842 Ins_UNKNOWN( EXEC_ARG_ args ); 8109 Ins_UNKNOWN( exc );
8843 break; 8110 break;
8844 8111
8845 case 0x85: /* SCANCTRL */ 8112 case 0x85: /* SCANCTRL */
8846 Ins_SCANCTRL( EXEC_ARG_ args ); 8113 Ins_SCANCTRL( exc, args );
8847 break; 8114 break;
8848 8115
8849 case 0x86: /* SDPVTL */ 8116 case 0x86: /* SDPvTL */
8850 case 0x87: /* SDPVTL */ 8117 case 0x87: /* SDPvTL */
8851 Ins_SDPVTL( EXEC_ARG_ args ); 8118 Ins_SDPVTL( exc, args );
8852 break; 8119 break;
8853 8120
8854 case 0x88: /* GETINFO */ 8121 case 0x88: /* GETINFO */
8855 Ins_GETINFO( EXEC_ARG_ args ); 8122 Ins_GETINFO( exc, args );
8856 break; 8123 break;
8857 8124
8858 case 0x89: /* IDEF */ 8125 case 0x89: /* IDEF */
8859 Ins_IDEF( EXEC_ARG_ args ); 8126 Ins_IDEF( exc, args );
8860 break; 8127 break;
8861 8128
8862 case 0x8A: /* ROLL */ 8129 case 0x8A: /* ROLL */
8863 Ins_ROLL( EXEC_ARG_ args ); 8130 Ins_ROLL( args );
8864 break; 8131 break;
8865 8132
8866 case 0x8B: /* MAX */ 8133 case 0x8B: /* MAX */
8867 DO_MAX 8134 Ins_MAX( args );
8868 break; 8135 break;
8869 8136
8870 case 0x8C: /* MIN */ 8137 case 0x8C: /* MIN */
8871 DO_MIN 8138 Ins_MIN( args );
8872 break; 8139 break;
8873 8140
8874 case 0x8D: /* SCANTYPE */ 8141 case 0x8D: /* SCANTYPE */
8875 Ins_SCANTYPE( EXEC_ARG_ args ); 8142 Ins_SCANTYPE( exc, args );
8876 break; 8143 break;
8877 8144
8878 case 0x8E: /* INSTCTRL */ 8145 case 0x8E: /* INSTCTRL */
8879 Ins_INSTCTRL( EXEC_ARG_ args ); 8146 Ins_INSTCTRL( exc, args );
8880 break; 8147 break;
8881 8148
8882 case 0x8F: 8149 case 0x8F:
8883 Ins_UNKNOWN( EXEC_ARG_ args ); 8150 Ins_UNKNOWN( exc );
8884 break; 8151 break;
8885 8152
8886 default: 8153 default:
8887 if ( opcode >= 0xE0 ) 8154 if ( opcode >= 0xE0 )
8888 Ins_MIRP( EXEC_ARG_ args ); 8155 Ins_MIRP( exc, args );
8889 else if ( opcode >= 0xC0 ) 8156 else if ( opcode >= 0xC0 )
8890 Ins_MDRP( EXEC_ARG_ args ); 8157 Ins_MDRP( exc, args );
8891 else if ( opcode >= 0xB8 ) 8158 else if ( opcode >= 0xB8 )
8892 Ins_PUSHW( EXEC_ARG_ args ); 8159 Ins_PUSHW( exc, args );
8893 else if ( opcode >= 0xB0 ) 8160 else if ( opcode >= 0xB0 )
8894 Ins_PUSHB( EXEC_ARG_ args ); 8161 Ins_PUSHB( exc, args );
8895 else 8162 else
8896 Ins_UNKNOWN( EXEC_ARG_ args ); 8163 Ins_UNKNOWN( exc );
8897 } 8164 }
8898
8899 } 8165 }
8900 8166
8901 #else 8167 if ( exc->error )
8902
8903 Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
8904
8905 #endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
8906
8907 if ( CUR.error )
8908 { 8168 {
8909 switch ( CUR.error ) 8169 switch ( exc->error )
8910 { 8170 {
8911 /* looking for redefined instructions */ 8171 /* looking for redefined instructions */
8912 case FT_ERR( Invalid_Opcode ): 8172 case FT_ERR( Invalid_Opcode ):
8913 { 8173 {
8914 TT_DefRecord* def = CUR.IDefs; 8174 TT_DefRecord* def = exc->IDefs;
8915 TT_DefRecord* limit = def + CUR.numIDefs; 8175 TT_DefRecord* limit = def + exc->numIDefs;
8916 8176
8917 8177
8918 for ( ; def < limit; def++ ) 8178 for ( ; def < limit; def++ )
8919 { 8179 {
8920 if ( def->active && CUR.opcode == (FT_Byte)def->opc ) 8180 if ( def->active && exc->opcode == (FT_Byte)def->opc )
8921 { 8181 {
8922 TT_CallRec* callrec; 8182 TT_CallRec* callrec;
8923 8183
8924 8184
8925 if ( CUR.callTop >= CUR.callSize ) 8185 if ( exc->callTop >= exc->callSize )
8926 { 8186 {
8927 CUR.error = FT_THROW( Invalid_Reference ); 8187 exc->error = FT_THROW( Invalid_Reference );
8928 goto LErrorLabel_; 8188 goto LErrorLabel_;
8929 } 8189 }
8930 8190
8931 callrec = &CUR.callStack[CUR.callTop]; 8191 callrec = &exc->callStack[exc->callTop];
8932 8192
8933 callrec->Caller_Range = CUR.curRange; 8193 callrec->Caller_Range = exc->curRange;
8934 callrec->Caller_IP = CUR.IP + 1; 8194 callrec->Caller_IP = exc->IP + 1;
8935 callrec->Cur_Count = 1; 8195 callrec->Cur_Count = 1;
8936 callrec->Def = def; 8196 callrec->Def = def;
8937 8197
8938 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) 8198 if ( Ins_Goto_CodeRange( exc,
8199 def->range,
8200 def->start ) == FAILURE )
8939 goto LErrorLabel_; 8201 goto LErrorLabel_;
8940 8202
8941 goto LSuiteLabel_; 8203 goto LSuiteLabel_;
8942 } 8204 }
8943 } 8205 }
8944 } 8206 }
8945 8207
8946 CUR.error = FT_THROW( Invalid_Opcode ); 8208 exc->error = FT_THROW( Invalid_Opcode );
8947 goto LErrorLabel_; 8209 goto LErrorLabel_;
8948 8210
8949 #if 0 8211 #if 0
8950 break; /* Unreachable code warning suppression. */ 8212 break; /* Unreachable code warning suppression. */
8951 /* Leave to remind in case a later change the editor */ 8213 /* Leave to remind in case a later change the editor */
8952 /* to consider break; */ 8214 /* to consider break; */
8953 #endif 8215 #endif
8954 8216
8955 default: 8217 default:
8956 goto LErrorLabel_; 8218 goto LErrorLabel_;
8957 8219
8958 #if 0 8220 #if 0
8959 break; 8221 break;
8960 #endif 8222 #endif
8961 } 8223 }
8962 } 8224 }
8963 8225
8964 CUR.top = CUR.new_top; 8226 exc->top = exc->new_top;
8965 8227
8966 if ( CUR.step_ins ) 8228 if ( exc->step_ins )
8967 CUR.IP += CUR.length; 8229 exc->IP += exc->length;
8968 8230
8969 /* increment instruction counter and check if we didn't */ 8231 /* increment instruction counter and check if we didn't */
8970 /* run this program for too long (e.g. infinite loops). */ 8232 /* run this program for too long (e.g. infinite loops). */
8971 if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) 8233 if ( ++ins_counter > MAX_RUNNABLE_OPCODES )
8972 return FT_THROW( Execution_Too_Long ); 8234 return FT_THROW( Execution_Too_Long );
8973 8235
8974 LSuiteLabel_: 8236 LSuiteLabel_:
8975 if ( CUR.IP >= CUR.codeSize ) 8237 if ( exc->IP >= exc->codeSize )
8976 { 8238 {
8977 if ( CUR.callTop > 0 ) 8239 if ( exc->callTop > 0 )
8978 { 8240 {
8979 CUR.error = FT_THROW( Code_Overflow ); 8241 exc->error = FT_THROW( Code_Overflow );
8980 goto LErrorLabel_; 8242 goto LErrorLabel_;
8981 } 8243 }
8982 else 8244 else
8983 goto LNo_Error_; 8245 goto LNo_Error_;
8984 } 8246 }
8985 } while ( !CUR.instruction_trap ); 8247 } while ( !exc->instruction_trap );
8986 8248
8987 LNo_Error_: 8249 LNo_Error_:
8988
8989 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
8990 *exc = cur;
8991 #endif
8992
8993 return FT_Err_Ok; 8250 return FT_Err_Ok;
8994 8251
8995 LErrorCodeOverflow_: 8252 LErrorCodeOverflow_:
8996 CUR.error = FT_THROW( Code_Overflow ); 8253 exc->error = FT_THROW( Code_Overflow );
8997 8254
8998 LErrorLabel_: 8255 LErrorLabel_:
8999
9000 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
9001 *exc = cur;
9002 #endif
9003
9004 /* If any errors have occurred, function tables may be broken. */ 8256 /* If any errors have occurred, function tables may be broken. */
9005 /* Force a re-execution of `prep' and `fpgm' tables if no */ 8257 /* Force a re-execution of `prep' and `fpgm' tables if no */
9006 /* bytecode debugger is run. */ 8258 /* bytecode debugger is run. */
9007 if ( CUR.error 8259 if ( exc->error &&
9008 && !CUR.instruction_trap 8260 !exc->instruction_trap &&
9009 && CUR.curRange == tt_coderange_glyph ) 8261 exc->curRange == tt_coderange_glyph )
9010 { 8262 {
9011 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); 8263 FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error ));
9012 exc->size->bytecode_ready = -1; 8264 exc->size->bytecode_ready = -1;
9013 exc->size->cvt_ready = -1; 8265 exc->size->cvt_ready = -1;
9014 } 8266 }
9015 8267
9016 return CUR.error; 8268 return exc->error;
9017 } 8269 }
9018 8270
9019 8271
9020 #endif /* TT_USE_BYTECODE_INTERPRETER */ 8272 #endif /* TT_USE_BYTECODE_INTERPRETER */
9021 8273
9022 8274
9023 /* END */ 8275 /* END */
OLDNEW
« no previous file with comments | « third_party/freetype/src/truetype/ttinterp.h ('k') | third_party/freetype/src/truetype/ttobjs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698