XFA: merge patch from CL 815103002
[pdfium.git] / third_party / freetype / src / truetype / ttinterp.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ttinterp.c                                                             */
4 /*                                                                         */
5 /*    TrueType bytecode interpreter (body).                                */
6 /*                                                                         */
7 /*  Copyright 1996-2014                                                    */
8 /*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17
18
19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */
20 /* issues; many thanks!                                                */
21
22
23 #include <ft2build.h>
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_CALC_H
26 #include FT_TRIGONOMETRY_H
27 #include FT_SYSTEM_H
28 #include FT_TRUETYPE_DRIVER_H
29
30 #include "ttinterp.h"
31 #include "tterrors.h"
32 #include "ttsubpix.h"
33
34
35 #ifdef TT_USE_BYTECODE_INTERPRETER
36
37
38   /*************************************************************************/
39   /*                                                                       */
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  */
42   /* messages during execution.                                            */
43   /*                                                                       */
44 #undef  FT_COMPONENT
45 #define FT_COMPONENT  trace_ttinterp
46
47   /*************************************************************************/
48   /*                                                                       */
49   /* 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   /* limited to a maximum number of opcodes defined below.                 */
52   /*                                                                       */
53 #define MAX_RUNNABLE_OPCODES  1000000L
54
55
56   /*************************************************************************/
57   /*                                                                       */
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 )
138
139
140   /*************************************************************************/
141   /*                                                                       */
142   /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
143   /* increase readability of the code.                                     */
144   /*                                                                       */
145   /*************************************************************************/
146
147
148 #define SKIP_Code() \
149           SkipCode( EXEC_ARG )
150
151 #define GET_ShortIns() \
152           GetShortIns( EXEC_ARG )
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
218
219   /*************************************************************************/
220   /*                                                                       */
221   /* Instruction dispatch function, as used by the interpreter.            */
222   /*                                                                       */
223   typedef void  (*TInstruction_Function)( INS_ARG );
224
225
226   /*************************************************************************/
227   /*                                                                       */
228   /* Two simple bounds-checking macros.                                    */
229   /*                                                                       */
230 #define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )
231 #define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )
232
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
241 #undef  SUCCESS
242 #define SUCCESS  0
243
244 #undef  FAILURE
245 #define FAILURE  1
246
247 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
248 #define GUESS_VECTOR( V )                                         \
249   if ( CUR.face->unpatented_hinting )                             \
250   {                                                               \
251     CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
252     CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
253   }
254 #else
255 #define GUESS_VECTOR( V )
256 #endif
257
258   /*************************************************************************/
259   /*                                                                       */
260   /*                        CODERANGE FUNCTIONS                            */
261   /*                                                                       */
262   /*************************************************************************/
263
264
265   /*************************************************************************/
266   /*                                                                       */
267   /* <Function>                                                            */
268   /*    TT_Goto_CodeRange                                                  */
269   /*                                                                       */
270   /* <Description>                                                         */
271   /*    Switches to a new code range (updates the code related elements in */
272   /*    `exec', and `IP').                                                 */
273   /*                                                                       */
274   /* <Input>                                                               */
275   /*    range :: The new execution code range.                             */
276   /*                                                                       */
277   /*    IP    :: The new IP in the new code range.                         */
278   /*                                                                       */
279   /* <InOut>                                                               */
280   /*    exec  :: The target execution context.                             */
281   /*                                                                       */
282   FT_LOCAL_DEF( void )
283   TT_Goto_CodeRange( TT_ExecContext  exec,
284                      FT_Int          range,
285                      FT_Long         IP )
286   {
287     TT_CodeRange*  coderange;
288
289
290     FT_ASSERT( range >= 1 && range <= 3 );
291
292     coderange = &exec->codeRangeTable[range - 1];
293
294     FT_ASSERT( coderange->base != NULL );
295
296     /* NOTE: Because the last instruction of a program may be a CALL */
297     /*       which will return to the first byte *after* the code    */
298     /*       range, we test for IP <= Size instead of IP < Size.     */
299     /*                                                               */
300     FT_ASSERT( (FT_ULong)IP <= coderange->size );
301
302     exec->code     = coderange->base;
303     exec->codeSize = coderange->size;
304     exec->IP       = IP;
305     exec->curRange = range;
306   }
307
308
309   /*************************************************************************/
310   /*                                                                       */
311   /* <Function>                                                            */
312   /*    TT_Set_CodeRange                                                   */
313   /*                                                                       */
314   /* <Description>                                                         */
315   /*    Sets a code range.                                                 */
316   /*                                                                       */
317   /* <Input>                                                               */
318   /*    range  :: The code range index.                                    */
319   /*                                                                       */
320   /*    base   :: The new code base.                                       */
321   /*                                                                       */
322   /*    length :: The range size in bytes.                                 */
323   /*                                                                       */
324   /* <InOut>                                                               */
325   /*    exec   :: The target execution context.                            */
326   /*                                                                       */
327   FT_LOCAL_DEF( void )
328   TT_Set_CodeRange( TT_ExecContext  exec,
329                     FT_Int          range,
330                     void*           base,
331                     FT_Long         length )
332   {
333     FT_ASSERT( range >= 1 && range <= 3 );
334
335     exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
336     exec->codeRangeTable[range - 1].size = length;
337   }
338
339
340   /*************************************************************************/
341   /*                                                                       */
342   /* <Function>                                                            */
343   /*    TT_Clear_CodeRange                                                 */
344   /*                                                                       */
345   /* <Description>                                                         */
346   /*    Clears a code range.                                               */
347   /*                                                                       */
348   /* <Input>                                                               */
349   /*    range :: The code range index.                                     */
350   /*                                                                       */
351   /* <InOut>                                                               */
352   /*    exec  :: The target execution context.                             */
353   /*                                                                       */
354   FT_LOCAL_DEF( void )
355   TT_Clear_CodeRange( TT_ExecContext  exec,
356                       FT_Int          range )
357   {
358     FT_ASSERT( range >= 1 && range <= 3 );
359
360     exec->codeRangeTable[range - 1].base = NULL;
361     exec->codeRangeTable[range - 1].size = 0;
362   }
363
364
365   /*************************************************************************/
366   /*                                                                       */
367   /*                   EXECUTION CONTEXT ROUTINES                          */
368   /*                                                                       */
369   /*************************************************************************/
370
371
372   /*************************************************************************/
373   /*                                                                       */
374   /* <Function>                                                            */
375   /*    TT_Done_Context                                                    */
376   /*                                                                       */
377   /* <Description>                                                         */
378   /*    Destroys a given context.                                          */
379   /*                                                                       */
380   /* <Input>                                                               */
381   /*    exec   :: A handle to the target execution context.                */
382   /*                                                                       */
383   /*    memory :: A handle to the parent memory object.                    */
384   /*                                                                       */
385   /* <Note>                                                                */
386   /*    Only the glyph loader and debugger should call this function.      */
387   /*                                                                       */
388   FT_LOCAL_DEF( void )
389   TT_Done_Context( TT_ExecContext  exec )
390   {
391     FT_Memory  memory = exec->memory;
392
393
394     /* points zone */
395     exec->maxPoints   = 0;
396     exec->maxContours = 0;
397
398     /* free stack */
399     FT_FREE( exec->stack );
400     exec->stackSize = 0;
401
402     /* free call stack */
403     FT_FREE( exec->callStack );
404     exec->callSize = 0;
405     exec->callTop  = 0;
406
407     /* free glyph code range */
408     FT_FREE( exec->glyphIns );
409     exec->glyphSize = 0;
410
411     exec->size = NULL;
412     exec->face = NULL;
413
414     FT_FREE( exec );
415   }
416
417
418   /*************************************************************************/
419   /*                                                                       */
420   /* <Function>                                                            */
421   /*    Init_Context                                                       */
422   /*                                                                       */
423   /* <Description>                                                         */
424   /*    Initializes a context object.                                      */
425   /*                                                                       */
426   /* <Input>                                                               */
427   /*    memory :: A handle to the parent memory object.                    */
428   /*                                                                       */
429   /* <InOut>                                                               */
430   /*    exec   :: A handle to the target execution context.                */
431   /*                                                                       */
432   /* <Return>                                                              */
433   /*    FreeType error code.  0 means success.                             */
434   /*                                                                       */
435   static FT_Error
436   Init_Context( TT_ExecContext  exec,
437                 FT_Memory       memory )
438   {
439     FT_Error  error;
440
441
442     FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));
443
444     exec->memory   = memory;
445     exec->callSize = 32;
446
447     if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )
448       goto Fail_Memory;
449
450     /* all values in the context are set to 0 already, but this is */
451     /* here as a remainder                                         */
452     exec->maxPoints   = 0;
453     exec->maxContours = 0;
454
455     exec->stackSize = 0;
456     exec->glyphSize = 0;
457
458     exec->stack     = NULL;
459     exec->glyphIns  = NULL;
460
461     exec->face = NULL;
462     exec->size = NULL;
463
464     return FT_Err_Ok;
465
466   Fail_Memory:
467     FT_ERROR(( "Init_Context: not enough memory for %p\n", exec ));
468     TT_Done_Context( exec );
469
470     return error;
471  }
472
473
474   /*************************************************************************/
475   /*                                                                       */
476   /* <Function>                                                            */
477   /*    Update_Max                                                         */
478   /*                                                                       */
479   /* <Description>                                                         */
480   /*    Checks the size of a buffer and reallocates it if necessary.       */
481   /*                                                                       */
482   /* <Input>                                                               */
483   /*    memory     :: A handle to the parent memory object.                */
484   /*                                                                       */
485   /*    multiplier :: The size in bytes of each element in the buffer.     */
486   /*                                                                       */
487   /*    new_max    :: The new capacity (size) of the buffer.               */
488   /*                                                                       */
489   /* <InOut>                                                               */
490   /*    size       :: The address of the buffer's current size expressed   */
491   /*                  in elements.                                         */
492   /*                                                                       */
493   /*    buff       :: The address of the buffer base pointer.              */
494   /*                                                                       */
495   /* <Return>                                                              */
496   /*    FreeType error code.  0 means success.                             */
497   /*                                                                       */
498   FT_LOCAL_DEF( FT_Error )
499   Update_Max( FT_Memory  memory,
500               FT_ULong*  size,
501               FT_Long    multiplier,
502               void*      _pbuff,
503               FT_ULong   new_max )
504   {
505     FT_Error  error;
506     void**    pbuff = (void**)_pbuff;
507
508
509     if ( *size < new_max )
510     {
511       if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
512         return error;
513       *size = new_max;
514     }
515
516     return FT_Err_Ok;
517   }
518
519
520   /*************************************************************************/
521   /*                                                                       */
522   /* <Function>                                                            */
523   /*    TT_Load_Context                                                    */
524   /*                                                                       */
525   /* <Description>                                                         */
526   /*    Prepare an execution context for glyph hinting.                    */
527   /*                                                                       */
528   /* <Input>                                                               */
529   /*    face :: A handle to the source face object.                        */
530   /*                                                                       */
531   /*    size :: A handle to the source size object.                        */
532   /*                                                                       */
533   /* <InOut>                                                               */
534   /*    exec :: A handle to the target execution context.                  */
535   /*                                                                       */
536   /* <Return>                                                              */
537   /*    FreeType error code.  0 means success.                             */
538   /*                                                                       */
539   /* <Note>                                                                */
540   /*    Only the glyph loader and debugger should call this function.      */
541   /*                                                                       */
542   FT_LOCAL_DEF( FT_Error )
543   TT_Load_Context( TT_ExecContext  exec,
544                    TT_Face         face,
545                    TT_Size         size )
546   {
547     FT_Int          i;
548     FT_ULong        tmp;
549     TT_MaxProfile*  maxp;
550     FT_Error        error;
551
552
553     exec->face = face;
554     maxp       = &face->max_profile;
555     exec->size = size;
556
557     if ( size )
558     {
559       exec->numFDefs   = size->num_function_defs;
560       exec->maxFDefs   = size->max_function_defs;
561       exec->numIDefs   = size->num_instruction_defs;
562       exec->maxIDefs   = size->max_instruction_defs;
563       exec->FDefs      = size->function_defs;
564       exec->IDefs      = size->instruction_defs;
565       exec->tt_metrics = size->ttmetrics;
566       exec->metrics    = size->metrics;
567
568       exec->maxFunc    = size->max_func;
569       exec->maxIns     = size->max_ins;
570
571       for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
572         exec->codeRangeTable[i] = size->codeRangeTable[i];
573
574       /* set graphics state */
575       exec->GS = size->GS;
576
577       exec->cvtSize = size->cvt_size;
578       exec->cvt     = size->cvt;
579
580       exec->storeSize = size->storage_size;
581       exec->storage   = size->storage;
582
583       exec->twilight  = size->twilight;
584
585       /* 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.   */
587       ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) );
588       exec->zp1 = exec->zp0;
589       exec->zp2 = exec->zp0;
590     }
591
592     /* XXX: We reserve a little more elements on the stack to deal safely */
593     /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
594     tmp = exec->stackSize;
595     error = Update_Max( exec->memory,
596                         &tmp,
597                         sizeof ( FT_F26Dot6 ),
598                         (void*)&exec->stack,
599                         maxp->maxStackElements + 32 );
600     exec->stackSize = (FT_UInt)tmp;
601     if ( error )
602       return error;
603
604     tmp = exec->glyphSize;
605     error = Update_Max( exec->memory,
606                         &tmp,
607                         sizeof ( FT_Byte ),
608                         (void*)&exec->glyphIns,
609                         maxp->maxSizeOfInstructions );
610     exec->glyphSize = (FT_UShort)tmp;
611     if ( error )
612       return error;
613
614     exec->pts.n_points   = 0;
615     exec->pts.n_contours = 0;
616
617     exec->zp1 = exec->pts;
618     exec->zp2 = exec->pts;
619     exec->zp0 = exec->pts;
620
621     exec->instruction_trap = FALSE;
622
623     return FT_Err_Ok;
624   }
625
626
627   /*************************************************************************/
628   /*                                                                       */
629   /* <Function>                                                            */
630   /*    TT_Save_Context                                                    */
631   /*                                                                       */
632   /* <Description>                                                         */
633   /*    Saves the code ranges in a `size' object.                          */
634   /*                                                                       */
635   /* <Input>                                                               */
636   /*    exec :: A handle to the source execution context.                  */
637   /*                                                                       */
638   /* <InOut>                                                               */
639   /*    size :: A handle to the target size object.                        */
640   /*                                                                       */
641   /* <Note>                                                                */
642   /*    Only the glyph loader and debugger should call this function.      */
643   /*                                                                       */
644   FT_LOCAL_DEF( void )
645   TT_Save_Context( TT_ExecContext  exec,
646                    TT_Size         size )
647   {
648     FT_Int  i;
649
650
651     /* XXX: Will probably disappear soon with all the code range */
652     /*      management, which is now rather obsolete.            */
653     /*                                                           */
654     size->num_function_defs    = exec->numFDefs;
655     size->num_instruction_defs = exec->numIDefs;
656
657     size->max_func = exec->maxFunc;
658     size->max_ins  = exec->maxIns;
659
660     for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
661       size->codeRangeTable[i] = exec->codeRangeTable[i];
662   }
663
664
665   /*************************************************************************/
666   /*                                                                       */
667   /* <Function>                                                            */
668   /*    TT_Run_Context                                                     */
669   /*                                                                       */
670   /* <Description>                                                         */
671   /*    Executes one or more instructions in the execution context.        */
672   /*                                                                       */
673   /* <Input>                                                               */
674   /*    debug :: A Boolean flag.  If set, the function sets some internal  */
675   /*             variables and returns immediately, otherwise TT_RunIns()  */
676   /*             is called.                                                */
677   /*                                                                       */
678   /*             This is commented out currently.                          */
679   /*                                                                       */
680   /* <Input>                                                               */
681   /*    exec  :: A handle to the target execution context.                 */
682   /*                                                                       */
683   /* <Return>                                                              */
684   /*    TrueType error code.  0 means success.                             */
685   /*                                                                       */
686   /* <Note>                                                                */
687   /*    Only the glyph loader and debugger should call this function.      */
688   /*                                                                       */
689   FT_LOCAL_DEF( FT_Error )
690   TT_Run_Context( TT_ExecContext  exec,
691                   FT_Bool         debug )
692   {
693     TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
694
695     exec->zp0 = exec->pts;
696     exec->zp1 = exec->pts;
697     exec->zp2 = exec->pts;
698
699     exec->GS.gep0 = 1;
700     exec->GS.gep1 = 1;
701     exec->GS.gep2 = 1;
702
703     exec->GS.projVector.x = 0x4000;
704     exec->GS.projVector.y = 0x0000;
705
706     exec->GS.freeVector = exec->GS.projVector;
707     exec->GS.dualVector = exec->GS.projVector;
708
709 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
710     exec->GS.both_x_axis = TRUE;
711 #endif
712
713     exec->GS.round_state = 1;
714     exec->GS.loop        = 1;
715
716     /* some glyphs leave something on the stack. so we clean it */
717     /* before a new execution.                                  */
718     exec->top     = 0;
719     exec->callTop = 0;
720
721 #if 1
722     FT_UNUSED( debug );
723
724     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   }
732
733
734   /* The default value for `scan_control' is documented as FALSE in the */
735   /* TrueType specification.  This is confusing since it implies a      */
736   /* Boolean value.  However, this is not the case, thus both the       */
737   /* default values of our `scan_type' and `scan_control' fields (which */
738   /* the documentation's `scan_control' variable is split into) are     */
739   /* zero.                                                              */
740
741   const TT_GraphicsState  tt_default_graphics_state =
742   {
743     0, 0, 0,
744     { 0x4000, 0 },
745     { 0x4000, 0 },
746     { 0x4000, 0 },
747
748 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
749     TRUE,
750 #endif
751
752     1, 64, 1,
753     TRUE, 68, 0, 0, 9, 3,
754     0, FALSE, 0, 1, 1, 1
755   };
756
757
758   /* documentation is in ttinterp.h */
759
760   FT_EXPORT_DEF( TT_ExecContext )
761   TT_New_Context( TT_Driver  driver )
762   {
763     FT_Memory  memory;
764
765
766     if ( !driver )
767       goto Fail;
768
769     memory = driver->root.root.memory;
770
771     if ( !driver->context )
772     {
773       FT_Error        error;
774       TT_ExecContext  exec;
775
776
777       /* allocate object */
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
792   Fail:
793     return NULL;
794   }
795
796
797   /*************************************************************************/
798   /*                                                                       */
799   /* 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'  */
801   /* table.                                                                */
802   /*                                                                       */
803   /* For each opcode, the first column gives the number of arguments that  */
804   /* are popped from the stack; the second one gives the number of those   */
805   /* that are pushed in result.                                            */
806   /*                                                                       */
807   /* Opcodes which have a varying number of parameters in the data stream  */
808   /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */
809   /* the `opcode_length' table, and the value in `Pop_Push_Count' is set   */
810   /* to zero.                                                              */
811   /*                                                                       */
812   /*************************************************************************/
813
814
815 #undef  PACK
816 #define PACK( x, y )  ( ( x << 4 ) | y )
817
818
819   static
820   const FT_Byte  Pop_Push_Count[256] =
821   {
822     /* opcodes are gathered in groups of 16 */
823     /* please keep the spaces as they are   */
824
825     /*  SVTCA  y  */  PACK( 0, 0 ),
826     /*  SVTCA  x  */  PACK( 0, 0 ),
827     /*  SPvTCA y  */  PACK( 0, 0 ),
828     /*  SPvTCA x  */  PACK( 0, 0 ),
829     /*  SFvTCA y  */  PACK( 0, 0 ),
830     /*  SFvTCA x  */  PACK( 0, 0 ),
831     /*  SPvTL //  */  PACK( 2, 0 ),
832     /*  SPvTL +   */  PACK( 2, 0 ),
833     /*  SFvTL //  */  PACK( 2, 0 ),
834     /*  SFvTL +   */  PACK( 2, 0 ),
835     /*  SPvFS     */  PACK( 2, 0 ),
836     /*  SFvFS     */  PACK( 2, 0 ),
837     /*  GPV       */  PACK( 0, 2 ),
838     /*  GFV       */  PACK( 0, 2 ),
839     /*  SFvTPv    */  PACK( 0, 0 ),
840     /*  ISECT     */  PACK( 5, 0 ),
841
842     /*  SRP0      */  PACK( 1, 0 ),
843     /*  SRP1      */  PACK( 1, 0 ),
844     /*  SRP2      */  PACK( 1, 0 ),
845     /*  SZP0      */  PACK( 1, 0 ),
846     /*  SZP1      */  PACK( 1, 0 ),
847     /*  SZP2      */  PACK( 1, 0 ),
848     /*  SZPS      */  PACK( 1, 0 ),
849     /*  SLOOP     */  PACK( 1, 0 ),
850     /*  RTG       */  PACK( 0, 0 ),
851     /*  RTHG      */  PACK( 0, 0 ),
852     /*  SMD       */  PACK( 1, 0 ),
853     /*  ELSE      */  PACK( 0, 0 ),
854     /*  JMPR      */  PACK( 1, 0 ),
855     /*  SCvTCi    */  PACK( 1, 0 ),
856     /*  SSwCi     */  PACK( 1, 0 ),
857     /*  SSW       */  PACK( 1, 0 ),
858
859     /*  DUP       */  PACK( 1, 2 ),
860     /*  POP       */  PACK( 1, 0 ),
861     /*  CLEAR     */  PACK( 0, 0 ),
862     /*  SWAP      */  PACK( 2, 2 ),
863     /*  DEPTH     */  PACK( 0, 1 ),
864     /*  CINDEX    */  PACK( 1, 1 ),
865     /*  MINDEX    */  PACK( 1, 0 ),
866     /*  AlignPTS  */  PACK( 2, 0 ),
867     /*  INS_$28   */  PACK( 0, 0 ),
868     /*  UTP       */  PACK( 1, 0 ),
869     /*  LOOPCALL  */  PACK( 2, 0 ),
870     /*  CALL      */  PACK( 1, 0 ),
871     /*  FDEF      */  PACK( 1, 0 ),
872     /*  ENDF      */  PACK( 0, 0 ),
873     /*  MDAP[0]   */  PACK( 1, 0 ),
874     /*  MDAP[1]   */  PACK( 1, 0 ),
875
876     /*  IUP[0]    */  PACK( 0, 0 ),
877     /*  IUP[1]    */  PACK( 0, 0 ),
878     /*  SHP[0]    */  PACK( 0, 0 ),
879     /*  SHP[1]    */  PACK( 0, 0 ),
880     /*  SHC[0]    */  PACK( 1, 0 ),
881     /*  SHC[1]    */  PACK( 1, 0 ),
882     /*  SHZ[0]    */  PACK( 1, 0 ),
883     /*  SHZ[1]    */  PACK( 1, 0 ),
884     /*  SHPIX     */  PACK( 1, 0 ),
885     /*  IP        */  PACK( 0, 0 ),
886     /*  MSIRP[0]  */  PACK( 2, 0 ),
887     /*  MSIRP[1]  */  PACK( 2, 0 ),
888     /*  AlignRP   */  PACK( 0, 0 ),
889     /*  RTDG      */  PACK( 0, 0 ),
890     /*  MIAP[0]   */  PACK( 2, 0 ),
891     /*  MIAP[1]   */  PACK( 2, 0 ),
892
893     /*  NPushB    */  PACK( 0, 0 ),
894     /*  NPushW    */  PACK( 0, 0 ),
895     /*  WS        */  PACK( 2, 0 ),
896     /*  RS        */  PACK( 1, 1 ),
897     /*  WCvtP     */  PACK( 2, 0 ),
898     /*  RCvt      */  PACK( 1, 1 ),
899     /*  GC[0]     */  PACK( 1, 1 ),
900     /*  GC[1]     */  PACK( 1, 1 ),
901     /*  SCFS      */  PACK( 2, 0 ),
902     /*  MD[0]     */  PACK( 2, 1 ),
903     /*  MD[1]     */  PACK( 2, 1 ),
904     /*  MPPEM     */  PACK( 0, 1 ),
905     /*  MPS       */  PACK( 0, 1 ),
906     /*  FlipON    */  PACK( 0, 0 ),
907     /*  FlipOFF   */  PACK( 0, 0 ),
908     /*  DEBUG     */  PACK( 1, 0 ),
909
910     /*  LT        */  PACK( 2, 1 ),
911     /*  LTEQ      */  PACK( 2, 1 ),
912     /*  GT        */  PACK( 2, 1 ),
913     /*  GTEQ      */  PACK( 2, 1 ),
914     /*  EQ        */  PACK( 2, 1 ),
915     /*  NEQ       */  PACK( 2, 1 ),
916     /*  ODD       */  PACK( 1, 1 ),
917     /*  EVEN      */  PACK( 1, 1 ),
918     /*  IF        */  PACK( 1, 0 ),
919     /*  EIF       */  PACK( 0, 0 ),
920     /*  AND       */  PACK( 2, 1 ),
921     /*  OR        */  PACK( 2, 1 ),
922     /*  NOT       */  PACK( 1, 1 ),
923     /*  DeltaP1   */  PACK( 1, 0 ),
924     /*  SDB       */  PACK( 1, 0 ),
925     /*  SDS       */  PACK( 1, 0 ),
926
927     /*  ADD       */  PACK( 2, 1 ),
928     /*  SUB       */  PACK( 2, 1 ),
929     /*  DIV       */  PACK( 2, 1 ),
930     /*  MUL       */  PACK( 2, 1 ),
931     /*  ABS       */  PACK( 1, 1 ),
932     /*  NEG       */  PACK( 1, 1 ),
933     /*  FLOOR     */  PACK( 1, 1 ),
934     /*  CEILING   */  PACK( 1, 1 ),
935     /*  ROUND[0]  */  PACK( 1, 1 ),
936     /*  ROUND[1]  */  PACK( 1, 1 ),
937     /*  ROUND[2]  */  PACK( 1, 1 ),
938     /*  ROUND[3]  */  PACK( 1, 1 ),
939     /*  NROUND[0] */  PACK( 1, 1 ),
940     /*  NROUND[1] */  PACK( 1, 1 ),
941     /*  NROUND[2] */  PACK( 1, 1 ),
942     /*  NROUND[3] */  PACK( 1, 1 ),
943
944     /*  WCvtF     */  PACK( 2, 0 ),
945     /*  DeltaP2   */  PACK( 1, 0 ),
946     /*  DeltaP3   */  PACK( 1, 0 ),
947     /*  DeltaCn[0] */ PACK( 1, 0 ),
948     /*  DeltaCn[1] */ PACK( 1, 0 ),
949     /*  DeltaCn[2] */ PACK( 1, 0 ),
950     /*  SROUND    */  PACK( 1, 0 ),
951     /*  S45Round  */  PACK( 1, 0 ),
952     /*  JROT      */  PACK( 2, 0 ),
953     /*  JROF      */  PACK( 2, 0 ),
954     /*  ROFF      */  PACK( 0, 0 ),
955     /*  INS_$7B   */  PACK( 0, 0 ),
956     /*  RUTG      */  PACK( 0, 0 ),
957     /*  RDTG      */  PACK( 0, 0 ),
958     /*  SANGW     */  PACK( 1, 0 ),
959     /*  AA        */  PACK( 1, 0 ),
960
961     /*  FlipPT    */  PACK( 0, 0 ),
962     /*  FlipRgON  */  PACK( 2, 0 ),
963     /*  FlipRgOFF */  PACK( 2, 0 ),
964     /*  INS_$83   */  PACK( 0, 0 ),
965     /*  INS_$84   */  PACK( 0, 0 ),
966     /*  ScanCTRL  */  PACK( 1, 0 ),
967     /*  SDPVTL[0] */  PACK( 2, 0 ),
968     /*  SDPVTL[1] */  PACK( 2, 0 ),
969     /*  GetINFO   */  PACK( 1, 1 ),
970     /*  IDEF      */  PACK( 1, 0 ),
971     /*  ROLL      */  PACK( 3, 3 ),
972     /*  MAX       */  PACK( 2, 1 ),
973     /*  MIN       */  PACK( 2, 1 ),
974     /*  ScanTYPE  */  PACK( 1, 0 ),
975     /*  InstCTRL  */  PACK( 2, 0 ),
976     /*  INS_$8F   */  PACK( 0, 0 ),
977
978     /*  INS_$90  */   PACK( 0, 0 ),
979     /*  INS_$91  */   PACK( 0, 0 ),
980     /*  INS_$92  */   PACK( 0, 0 ),
981     /*  INS_$93  */   PACK( 0, 0 ),
982     /*  INS_$94  */   PACK( 0, 0 ),
983     /*  INS_$95  */   PACK( 0, 0 ),
984     /*  INS_$96  */   PACK( 0, 0 ),
985     /*  INS_$97  */   PACK( 0, 0 ),
986     /*  INS_$98  */   PACK( 0, 0 ),
987     /*  INS_$99  */   PACK( 0, 0 ),
988     /*  INS_$9A  */   PACK( 0, 0 ),
989     /*  INS_$9B  */   PACK( 0, 0 ),
990     /*  INS_$9C  */   PACK( 0, 0 ),
991     /*  INS_$9D  */   PACK( 0, 0 ),
992     /*  INS_$9E  */   PACK( 0, 0 ),
993     /*  INS_$9F  */   PACK( 0, 0 ),
994
995     /*  INS_$A0  */   PACK( 0, 0 ),
996     /*  INS_$A1  */   PACK( 0, 0 ),
997     /*  INS_$A2  */   PACK( 0, 0 ),
998     /*  INS_$A3  */   PACK( 0, 0 ),
999     /*  INS_$A4  */   PACK( 0, 0 ),
1000     /*  INS_$A5  */   PACK( 0, 0 ),
1001     /*  INS_$A6  */   PACK( 0, 0 ),
1002     /*  INS_$A7  */   PACK( 0, 0 ),
1003     /*  INS_$A8  */   PACK( 0, 0 ),
1004     /*  INS_$A9  */   PACK( 0, 0 ),
1005     /*  INS_$AA  */   PACK( 0, 0 ),
1006     /*  INS_$AB  */   PACK( 0, 0 ),
1007     /*  INS_$AC  */   PACK( 0, 0 ),
1008     /*  INS_$AD  */   PACK( 0, 0 ),
1009     /*  INS_$AE  */   PACK( 0, 0 ),
1010     /*  INS_$AF  */   PACK( 0, 0 ),
1011
1012     /*  PushB[0]  */  PACK( 0, 1 ),
1013     /*  PushB[1]  */  PACK( 0, 2 ),
1014     /*  PushB[2]  */  PACK( 0, 3 ),
1015     /*  PushB[3]  */  PACK( 0, 4 ),
1016     /*  PushB[4]  */  PACK( 0, 5 ),
1017     /*  PushB[5]  */  PACK( 0, 6 ),
1018     /*  PushB[6]  */  PACK( 0, 7 ),
1019     /*  PushB[7]  */  PACK( 0, 8 ),
1020     /*  PushW[0]  */  PACK( 0, 1 ),
1021     /*  PushW[1]  */  PACK( 0, 2 ),
1022     /*  PushW[2]  */  PACK( 0, 3 ),
1023     /*  PushW[3]  */  PACK( 0, 4 ),
1024     /*  PushW[4]  */  PACK( 0, 5 ),
1025     /*  PushW[5]  */  PACK( 0, 6 ),
1026     /*  PushW[6]  */  PACK( 0, 7 ),
1027     /*  PushW[7]  */  PACK( 0, 8 ),
1028
1029     /*  MDRP[00]  */  PACK( 1, 0 ),
1030     /*  MDRP[01]  */  PACK( 1, 0 ),
1031     /*  MDRP[02]  */  PACK( 1, 0 ),
1032     /*  MDRP[03]  */  PACK( 1, 0 ),
1033     /*  MDRP[04]  */  PACK( 1, 0 ),
1034     /*  MDRP[05]  */  PACK( 1, 0 ),
1035     /*  MDRP[06]  */  PACK( 1, 0 ),
1036     /*  MDRP[07]  */  PACK( 1, 0 ),
1037     /*  MDRP[08]  */  PACK( 1, 0 ),
1038     /*  MDRP[09]  */  PACK( 1, 0 ),
1039     /*  MDRP[10]  */  PACK( 1, 0 ),
1040     /*  MDRP[11]  */  PACK( 1, 0 ),
1041     /*  MDRP[12]  */  PACK( 1, 0 ),
1042     /*  MDRP[13]  */  PACK( 1, 0 ),
1043     /*  MDRP[14]  */  PACK( 1, 0 ),
1044     /*  MDRP[15]  */  PACK( 1, 0 ),
1045
1046     /*  MDRP[16]  */  PACK( 1, 0 ),
1047     /*  MDRP[17]  */  PACK( 1, 0 ),
1048     /*  MDRP[18]  */  PACK( 1, 0 ),
1049     /*  MDRP[19]  */  PACK( 1, 0 ),
1050     /*  MDRP[20]  */  PACK( 1, 0 ),
1051     /*  MDRP[21]  */  PACK( 1, 0 ),
1052     /*  MDRP[22]  */  PACK( 1, 0 ),
1053     /*  MDRP[23]  */  PACK( 1, 0 ),
1054     /*  MDRP[24]  */  PACK( 1, 0 ),
1055     /*  MDRP[25]  */  PACK( 1, 0 ),
1056     /*  MDRP[26]  */  PACK( 1, 0 ),
1057     /*  MDRP[27]  */  PACK( 1, 0 ),
1058     /*  MDRP[28]  */  PACK( 1, 0 ),
1059     /*  MDRP[29]  */  PACK( 1, 0 ),
1060     /*  MDRP[30]  */  PACK( 1, 0 ),
1061     /*  MDRP[31]  */  PACK( 1, 0 ),
1062
1063     /*  MIRP[00]  */  PACK( 2, 0 ),
1064     /*  MIRP[01]  */  PACK( 2, 0 ),
1065     /*  MIRP[02]  */  PACK( 2, 0 ),
1066     /*  MIRP[03]  */  PACK( 2, 0 ),
1067     /*  MIRP[04]  */  PACK( 2, 0 ),
1068     /*  MIRP[05]  */  PACK( 2, 0 ),
1069     /*  MIRP[06]  */  PACK( 2, 0 ),
1070     /*  MIRP[07]  */  PACK( 2, 0 ),
1071     /*  MIRP[08]  */  PACK( 2, 0 ),
1072     /*  MIRP[09]  */  PACK( 2, 0 ),
1073     /*  MIRP[10]  */  PACK( 2, 0 ),
1074     /*  MIRP[11]  */  PACK( 2, 0 ),
1075     /*  MIRP[12]  */  PACK( 2, 0 ),
1076     /*  MIRP[13]  */  PACK( 2, 0 ),
1077     /*  MIRP[14]  */  PACK( 2, 0 ),
1078     /*  MIRP[15]  */  PACK( 2, 0 ),
1079
1080     /*  MIRP[16]  */  PACK( 2, 0 ),
1081     /*  MIRP[17]  */  PACK( 2, 0 ),
1082     /*  MIRP[18]  */  PACK( 2, 0 ),
1083     /*  MIRP[19]  */  PACK( 2, 0 ),
1084     /*  MIRP[20]  */  PACK( 2, 0 ),
1085     /*  MIRP[21]  */  PACK( 2, 0 ),
1086     /*  MIRP[22]  */  PACK( 2, 0 ),
1087     /*  MIRP[23]  */  PACK( 2, 0 ),
1088     /*  MIRP[24]  */  PACK( 2, 0 ),
1089     /*  MIRP[25]  */  PACK( 2, 0 ),
1090     /*  MIRP[26]  */  PACK( 2, 0 ),
1091     /*  MIRP[27]  */  PACK( 2, 0 ),
1092     /*  MIRP[28]  */  PACK( 2, 0 ),
1093     /*  MIRP[29]  */  PACK( 2, 0 ),
1094     /*  MIRP[30]  */  PACK( 2, 0 ),
1095     /*  MIRP[31]  */  PACK( 2, 0 )
1096   };
1097
1098
1099 #ifdef FT_DEBUG_LEVEL_TRACE
1100
1101   static
1102   const char*  const opcode_name[256] =
1103   {
1104     "SVTCA y",
1105     "SVTCA x",
1106     "SPvTCA y",
1107     "SPvTCA x",
1108     "SFvTCA y",
1109     "SFvTCA x",
1110     "SPvTL ||",
1111     "SPvTL +",
1112     "SFvTL ||",
1113     "SFvTL +",
1114     "SPvFS",
1115     "SFvFS",
1116     "GPV",
1117     "GFV",
1118     "SFvTPv",
1119     "ISECT",
1120
1121     "SRP0",
1122     "SRP1",
1123     "SRP2",
1124     "SZP0",
1125     "SZP1",
1126     "SZP2",
1127     "SZPS",
1128     "SLOOP",
1129     "RTG",
1130     "RTHG",
1131     "SMD",
1132     "ELSE",
1133     "JMPR",
1134     "SCvTCi",
1135     "SSwCi",
1136     "SSW",
1137
1138     "DUP",
1139     "POP",
1140     "CLEAR",
1141     "SWAP",
1142     "DEPTH",
1143     "CINDEX",
1144     "MINDEX",
1145     "AlignPTS",
1146     "INS_$28",
1147     "UTP",
1148     "LOOPCALL",
1149     "CALL",
1150     "FDEF",
1151     "ENDF",
1152     "MDAP[0]",
1153     "MDAP[1]",
1154
1155     "IUP[0]",
1156     "IUP[1]",
1157     "SHP[0]",
1158     "SHP[1]",
1159     "SHC[0]",
1160     "SHC[1]",
1161     "SHZ[0]",
1162     "SHZ[1]",
1163     "SHPIX",
1164     "IP",
1165     "MSIRP[0]",
1166     "MSIRP[1]",
1167     "AlignRP",
1168     "RTDG",
1169     "MIAP[0]",
1170     "MIAP[1]",
1171
1172     "NPushB",
1173     "NPushW",
1174     "WS",
1175     "RS",
1176     "WCvtP",
1177     "RCvt",
1178     "GC[0]",
1179     "GC[1]",
1180     "SCFS",
1181     "MD[0]",
1182     "MD[1]",
1183     "MPPEM",
1184     "MPS",
1185     "FlipON",
1186     "FlipOFF",
1187     "DEBUG",
1188
1189     "LT",
1190     "LTEQ",
1191     "GT",
1192     "GTEQ",
1193     "EQ",
1194     "NEQ",
1195     "ODD",
1196     "EVEN",
1197     "IF",
1198     "EIF",
1199     "AND",
1200     "OR",
1201     "NOT",
1202     "DeltaP1",
1203     "SDB",
1204     "SDS",
1205
1206     "ADD",
1207     "SUB",
1208     "DIV",
1209     "MUL",
1210     "ABS",
1211     "NEG",
1212     "FLOOR",
1213     "CEILING",
1214     "ROUND[0]",
1215     "ROUND[1]",
1216     "ROUND[2]",
1217     "ROUND[3]",
1218     "NROUND[0]",
1219     "NROUND[1]",
1220     "NROUND[2]",
1221     "NROUND[3]",
1222
1223     "WCvtF",
1224     "DeltaP2",
1225     "DeltaP3",
1226     "DeltaCn[0]",
1227     "DeltaCn[1]",
1228     "DeltaCn[2]",
1229     "SROUND",
1230     "S45Round",
1231     "JROT",
1232     "JROF",
1233     "ROFF",
1234     "INS_$7B",
1235     "RUTG",
1236     "RDTG",
1237     "SANGW",
1238     "AA",
1239
1240     "FlipPT",
1241     "FlipRgON",
1242     "FlipRgOFF",
1243     "INS_$83",
1244     "INS_$84",
1245     "ScanCTRL",
1246     "SDVPTL[0]",
1247     "SDVPTL[1]",
1248     "GetINFO",
1249     "IDEF",
1250     "ROLL",
1251     "MAX",
1252     "MIN",
1253     "ScanTYPE",
1254     "InstCTRL",
1255     "INS_$8F",
1256
1257     "INS_$90",
1258     "INS_$91",
1259     "INS_$92",
1260     "INS_$93",
1261     "INS_$94",
1262     "INS_$95",
1263     "INS_$96",
1264     "INS_$97",
1265     "INS_$98",
1266     "INS_$99",
1267     "INS_$9A",
1268     "INS_$9B",
1269     "INS_$9C",
1270     "INS_$9D",
1271     "INS_$9E",
1272     "INS_$9F",
1273
1274     "INS_$A0",
1275     "INS_$A1",
1276     "INS_$A2",
1277     "INS_$A3",
1278     "INS_$A4",
1279     "INS_$A5",
1280     "INS_$A6",
1281     "INS_$A7",
1282     "INS_$A8",
1283     "INS_$A9",
1284     "INS_$AA",
1285     "INS_$AB",
1286     "INS_$AC",
1287     "INS_$AD",
1288     "INS_$AE",
1289     "INS_$AF",
1290
1291     "PushB[0]",
1292     "PushB[1]",
1293     "PushB[2]",
1294     "PushB[3]",
1295     "PushB[4]",
1296     "PushB[5]",
1297     "PushB[6]",
1298     "PushB[7]",
1299     "PushW[0]",
1300     "PushW[1]",
1301     "PushW[2]",
1302     "PushW[3]",
1303     "PushW[4]",
1304     "PushW[5]",
1305     "PushW[6]",
1306     "PushW[7]",
1307
1308     "MDRP[00]",
1309     "MDRP[01]",
1310     "MDRP[02]",
1311     "MDRP[03]",
1312     "MDRP[04]",
1313     "MDRP[05]",
1314     "MDRP[06]",
1315     "MDRP[07]",
1316     "MDRP[08]",
1317     "MDRP[09]",
1318     "MDRP[10]",
1319     "MDRP[11]",
1320     "MDRP[12]",
1321     "MDRP[13]",
1322     "MDRP[14]",
1323     "MDRP[15]",
1324
1325     "MDRP[16]",
1326     "MDRP[17]",
1327     "MDRP[18]",
1328     "MDRP[19]",
1329     "MDRP[20]",
1330     "MDRP[21]",
1331     "MDRP[22]",
1332     "MDRP[23]",
1333     "MDRP[24]",
1334     "MDRP[25]",
1335     "MDRP[26]",
1336     "MDRP[27]",
1337     "MDRP[28]",
1338     "MDRP[29]",
1339     "MDRP[30]",
1340     "MDRP[31]",
1341
1342     "MIRP[00]",
1343     "MIRP[01]",
1344     "MIRP[02]",
1345     "MIRP[03]",
1346     "MIRP[04]",
1347     "MIRP[05]",
1348     "MIRP[06]",
1349     "MIRP[07]",
1350     "MIRP[08]",
1351     "MIRP[09]",
1352     "MIRP[10]",
1353     "MIRP[11]",
1354     "MIRP[12]",
1355     "MIRP[13]",
1356     "MIRP[14]",
1357     "MIRP[15]",
1358
1359     "MIRP[16]",
1360     "MIRP[17]",
1361     "MIRP[18]",
1362     "MIRP[19]",
1363     "MIRP[20]",
1364     "MIRP[21]",
1365     "MIRP[22]",
1366     "MIRP[23]",
1367     "MIRP[24]",
1368     "MIRP[25]",
1369     "MIRP[26]",
1370     "MIRP[27]",
1371     "MIRP[28]",
1372     "MIRP[29]",
1373     "MIRP[30]",
1374     "MIRP[31]"
1375   };
1376
1377 #endif /* FT_DEBUG_LEVEL_TRACE */
1378
1379
1380   static
1381   const FT_Char  opcode_length[256] =
1382   {
1383     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,
1385     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1386     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1387
1388    -1,-2, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1389     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1390     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1391     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1392
1393     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1394     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1395     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1396     2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,
1397
1398     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1399     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1400     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
1401     1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1
1402   };
1403
1404 #undef PACK
1405
1406
1407 #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
1408
1409 #if defined( __arm__ )                                 && \
1410     ( defined( __thumb2__ ) || !defined( __thumb__ ) )
1411
1412 #define TT_MulFix14  TT_MulFix14_arm
1413
1414   static FT_Int32
1415   TT_MulFix14_arm( FT_Int32  a,
1416                    FT_Int    b )
1417   {
1418     FT_Int32  t, t2;
1419
1420
1421 #if defined( __CC_ARM ) || defined( __ARMCC__ )
1422
1423     __asm
1424     {
1425       smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
1426       mov   a,  t,  asr #31         /* a   = (hi >> 31) */
1427       add   a,  a,  #0x2000         /* a  += 0x2000 */
1428       adds  t2, t2, a               /* t2 += a */
1429       adc   t,  t,  #0              /* t  += carry */
1430       mov   a,  t2, lsr #14         /* a   = t2 >> 14 */
1431       orr   a,  a,  t,  lsl #18     /* a  |= t << 18 */
1432     }
1433
1434 #elif defined( __GNUC__ )
1435
1436     __asm__ __volatile__ (
1437       "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
1438       "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
1439 #if defined( __clang__ ) && defined( __thumb2__ )
1440       "add.w  %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
1441 #else
1442       "add    %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
1443 #endif
1444       "adds   %1, %1, %0\n\t"           /* %1 += %0 */
1445       "adc    %2, %2, #0\n\t"           /* %2 += carry */
1446       "mov    %0, %1, lsr #14\n\t"      /* %0  = %1 >> 16 */
1447       "orr    %0, %0, %2, lsl #18\n\t"  /* %0 |= %2 << 16 */
1448       : "=r"(a), "=&r"(t2), "=&r"(t)
1449       : "r"(a), "r"(b)
1450       : "cc" );
1451
1452 #endif
1453
1454     return a;
1455   }
1456
1457 #endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */
1458
1459 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
1460
1461
1462 #if defined( __GNUC__ )                              && \
1463     ( defined( __i386__ ) || defined( __x86_64__ ) )
1464
1465 #define TT_MulFix14  TT_MulFix14_long_long
1466
1467   /* Temporarily disable the warning that C90 doesn't support `long long'. */
1468 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1469 #pragma GCC diagnostic push
1470 #endif
1471 #pragma GCC diagnostic ignored "-Wlong-long"
1472
1473   /* This is declared `noinline' because inlining the function results */
1474   /* in slower code.  The `pure' attribute indicates that the result   */
1475   /* only depends on the parameters.                                   */
1476   static __attribute__(( noinline ))
1477          __attribute__(( pure )) FT_Int32
1478   TT_MulFix14_long_long( FT_Int32  a,
1479                          FT_Int    b )
1480   {
1481
1482     long long  ret = (long long)a * b;
1483
1484     /* The following line assumes that right shifting of signed values */
1485     /* will actually preserve the sign bit.  The exact behaviour is    */
1486     /* undefined, but this is true on x86 and x86_64.                  */
1487     long long  tmp = ret >> 63;
1488
1489
1490     ret += 0x2000 + tmp;
1491
1492     return (FT_Int32)( ret >> 14 );
1493   }
1494
1495 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1496 #pragma GCC diagnostic pop
1497 #endif
1498
1499 #endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */
1500
1501
1502 #ifndef TT_MulFix14
1503
1504   /* Compute (a*b)/2^14 with maximum accuracy and rounding.  */
1505   /* This is optimized to be faster than calling FT_MulFix() */
1506   /* for platforms where sizeof(int) == 2.                   */
1507   static FT_Int32
1508   TT_MulFix14( FT_Int32  a,
1509                FT_Int    b )
1510   {
1511     FT_Int32   sign;
1512     FT_UInt32  ah, al, mid, lo, hi;
1513
1514
1515     sign = a ^ b;
1516
1517     if ( a < 0 )
1518       a = -a;
1519     if ( b < 0 )
1520       b = -b;
1521
1522     ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
1523     al = (FT_UInt32)( a & 0xFFFFU );
1524
1525     lo    = al * b;
1526     mid   = ah * b;
1527     hi    = mid >> 16;
1528     mid   = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
1529     lo   += mid;
1530     if ( lo < mid )
1531       hi += 1;
1532
1533     mid = ( lo >> 14 ) | ( hi << 18 );
1534
1535     return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
1536   }
1537
1538 #endif  /* !TT_MulFix14 */
1539
1540
1541 #if defined( __GNUC__ )        && \
1542     ( defined( __i386__ )   ||    \
1543       defined( __x86_64__ ) ||    \
1544       defined( __arm__ )    )
1545
1546 #define TT_DotFix14  TT_DotFix14_long_long
1547
1548 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1549 #pragma GCC diagnostic push
1550 #endif
1551 #pragma GCC diagnostic ignored "-Wlong-long"
1552
1553   static __attribute__(( pure )) FT_Int32
1554   TT_DotFix14_long_long( FT_Int32  ax,
1555                          FT_Int32  ay,
1556                          FT_Int    bx,
1557                          FT_Int    by )
1558   {
1559     /* Temporarily disable the warning that C90 doesn't support */
1560     /* `long long'.                                             */
1561
1562     long long  temp1 = (long long)ax * bx;
1563     long long  temp2 = (long long)ay * by;
1564
1565
1566     temp1 += temp2;
1567     temp2  = temp1 >> 63;
1568     temp1 += 0x2000 + temp2;
1569
1570     return (FT_Int32)( temp1 >> 14 );
1571
1572   }
1573
1574 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1575 #pragma GCC diagnostic pop
1576 #endif
1577
1578 #endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */
1579
1580
1581 #ifndef TT_DotFix14
1582
1583   /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */
1584   static FT_Int32
1585   TT_DotFix14( FT_Int32  ax,
1586                FT_Int32  ay,
1587                FT_Int    bx,
1588                FT_Int    by )
1589   {
1590     FT_Int32   m, s, hi1, hi2, hi;
1591     FT_UInt32  l, lo1, lo2, lo;
1592
1593
1594     /* compute ax*bx as 64-bit value */
1595     l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
1596     m = ( ax >> 16 ) * bx;
1597
1598     lo1 = l + ( (FT_UInt32)m << 16 );
1599     hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
1600
1601     /* compute ay*by as 64-bit value */
1602     l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
1603     m = ( ay >> 16 ) * by;
1604
1605     lo2 = l + ( (FT_UInt32)m << 16 );
1606     hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
1607
1608     /* add them */
1609     lo = lo1 + lo2;
1610     hi = hi1 + hi2 + ( lo < lo1 );
1611
1612     /* divide the result by 2^14 with rounding */
1613     s   = hi >> 31;
1614     l   = lo + (FT_UInt32)s;
1615     hi += s + ( l < lo );
1616     lo  = l;
1617
1618     l   = lo + 0x2000U;
1619     hi += ( l < lo );
1620
1621     return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
1622   }
1623
1624 #endif /* TT_DotFix14 */
1625
1626
1627   /*************************************************************************/
1628   /*                                                                       */
1629   /* <Function>                                                            */
1630   /*    Current_Ratio                                                      */
1631   /*                                                                       */
1632   /* <Description>                                                         */
1633   /*    Returns the current aspect ratio scaling factor depending on the   */
1634   /*    projection vector's state and device resolutions.                  */
1635   /*                                                                       */
1636   /* <Return>                                                              */
1637   /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
1638   /*                                                                       */
1639   static FT_Long
1640   Current_Ratio( EXEC_OP )
1641   {
1642     if ( !CUR.tt_metrics.ratio )
1643     {
1644 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1645       if ( CUR.face->unpatented_hinting )
1646       {
1647         if ( CUR.GS.both_x_axis )
1648           CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
1649         else
1650           CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
1651       }
1652       else
1653 #endif
1654       {
1655         if ( CUR.GS.projVector.y == 0 )
1656           CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
1657
1658         else if ( CUR.GS.projVector.x == 0 )
1659           CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
1660
1661         else
1662         {
1663           FT_F26Dot6  x, y;
1664
1665
1666           x = TT_MulFix14( CUR.tt_metrics.x_ratio,
1667                            CUR.GS.projVector.x );
1668           y = TT_MulFix14( CUR.tt_metrics.y_ratio,
1669                            CUR.GS.projVector.y );
1670           CUR.tt_metrics.ratio = FT_Hypot( x, y );
1671         }
1672       }
1673     }
1674     return CUR.tt_metrics.ratio;
1675   }
1676
1677
1678   FT_CALLBACK_DEF( FT_Long )
1679   Current_Ppem( EXEC_OP )
1680   {
1681     return CUR.tt_metrics.ppem;
1682   }
1683
1684
1685   FT_CALLBACK_DEF( FT_Long )
1686   Current_Ppem_Stretched( EXEC_OP )
1687   {
1688     return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
1689   }
1690
1691
1692   /*************************************************************************/
1693   /*                                                                       */
1694   /* Functions related to the control value table (CVT).                   */
1695   /*                                                                       */
1696   /*************************************************************************/
1697
1698
1699   FT_CALLBACK_DEF( FT_F26Dot6 )
1700   Read_CVT( EXEC_OP_ FT_ULong  idx )
1701   {
1702     return CUR.cvt[idx];
1703   }
1704
1705
1706   FT_CALLBACK_DEF( FT_F26Dot6 )
1707   Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )
1708   {
1709     return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
1710   }
1711
1712
1713   FT_CALLBACK_DEF( void )
1714   Write_CVT( EXEC_OP_ FT_ULong    idx,
1715                       FT_F26Dot6  value )
1716   {
1717     CUR.cvt[idx] = value;
1718   }
1719
1720
1721   FT_CALLBACK_DEF( void )
1722   Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
1723                                 FT_F26Dot6  value )
1724   {
1725     CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
1726   }
1727
1728
1729   FT_CALLBACK_DEF( void )
1730   Move_CVT( EXEC_OP_ FT_ULong    idx,
1731                      FT_F26Dot6  value )
1732   {
1733     CUR.cvt[idx] += value;
1734   }
1735
1736
1737   FT_CALLBACK_DEF( void )
1738   Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
1739                                FT_F26Dot6  value )
1740   {
1741     CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
1742   }
1743
1744
1745   /*************************************************************************/
1746   /*                                                                       */
1747   /* <Function>                                                            */
1748   /*    GetShortIns                                                        */
1749   /*                                                                       */
1750   /* <Description>                                                         */
1751   /*    Returns a short integer taken from the instruction stream at       */
1752   /*    address IP.                                                        */
1753   /*                                                                       */
1754   /* <Return>                                                              */
1755   /*    Short read at code[IP].                                            */
1756   /*                                                                       */
1757   /* <Note>                                                                */
1758   /*    This one could become a macro.                                     */
1759   /*                                                                       */
1760   static FT_Short
1761   GetShortIns( EXEC_OP )
1762   {
1763     /* Reading a byte stream so there is no endianess (DaveP) */
1764     CUR.IP += 2;
1765     return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
1766                          CUR.code[CUR.IP - 1]      );
1767   }
1768
1769
1770   /*************************************************************************/
1771   /*                                                                       */
1772   /* <Function>                                                            */
1773   /*    Ins_Goto_CodeRange                                                 */
1774   /*                                                                       */
1775   /* <Description>                                                         */
1776   /*    Goes to a certain code range in the instruction stream.            */
1777   /*                                                                       */
1778   /* <Input>                                                               */
1779   /*    aRange :: The index of the code range.                             */
1780   /*                                                                       */
1781   /*    aIP    :: The new IP address in the code range.                    */
1782   /*                                                                       */
1783   /* <Return>                                                              */
1784   /*    SUCCESS or FAILURE.                                                */
1785   /*                                                                       */
1786   static FT_Bool
1787   Ins_Goto_CodeRange( EXEC_OP_ FT_Int    aRange,
1788                                FT_ULong  aIP )
1789   {
1790     TT_CodeRange*  range;
1791
1792
1793     if ( aRange < 1 || aRange > 3 )
1794     {
1795       CUR.error = FT_THROW( Bad_Argument );
1796       return FAILURE;
1797     }
1798
1799     range = &CUR.codeRangeTable[aRange - 1];
1800
1801     if ( range->base == NULL )     /* invalid coderange */
1802     {
1803       CUR.error = FT_THROW( Invalid_CodeRange );
1804       return FAILURE;
1805     }
1806
1807     /* NOTE: Because the last instruction of a program may be a CALL */
1808     /*       which will return to the first byte *after* the code    */
1809     /*       range, we test for aIP <= Size, instead of aIP < Size.  */
1810
1811     if ( aIP > range->size )
1812     {
1813       CUR.error = FT_THROW( Code_Overflow );
1814       return FAILURE;
1815     }
1816
1817     CUR.code     = range->base;
1818     CUR.codeSize = range->size;
1819     CUR.IP       = aIP;
1820     CUR.curRange = aRange;
1821
1822     return SUCCESS;
1823   }
1824
1825
1826   /*************************************************************************/
1827   /*                                                                       */
1828   /* <Function>                                                            */
1829   /*    Direct_Move                                                        */
1830   /*                                                                       */
1831   /* <Description>                                                         */
1832   /*    Moves a point by a given distance along the freedom vector.  The   */
1833   /*    point will be `touched'.                                           */
1834   /*                                                                       */
1835   /* <Input>                                                               */
1836   /*    point    :: The index of the point to move.                        */
1837   /*                                                                       */
1838   /*    distance :: The distance to apply.                                 */
1839   /*                                                                       */
1840   /* <InOut>                                                               */
1841   /*    zone     :: The affected glyph zone.                               */
1842   /*                                                                       */
1843   static void
1844   Direct_Move( EXEC_OP_ TT_GlyphZone  zone,
1845                         FT_UShort     point,
1846                         FT_F26Dot6    distance )
1847   {
1848     FT_F26Dot6  v;
1849
1850
1851 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1852     FT_ASSERT( !CUR.face->unpatented_hinting );
1853 #endif
1854
1855     v = CUR.GS.freeVector.x;
1856
1857     if ( v != 0 )
1858     {
1859 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1860       if ( !SUBPIXEL_HINTING                                     ||
1861            ( !CUR.ignore_x_mode                                ||
1862              ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
1863 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1864         zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
1865
1866       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
1867     }
1868
1869     v = CUR.GS.freeVector.y;
1870
1871     if ( v != 0 )
1872     {
1873       zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
1874
1875       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
1876     }
1877   }
1878
1879
1880   /*************************************************************************/
1881   /*                                                                       */
1882   /* <Function>                                                            */
1883   /*    Direct_Move_Orig                                                   */
1884   /*                                                                       */
1885   /* <Description>                                                         */
1886   /*    Moves the *original* position of a point by a given distance along */
1887   /*    the freedom vector.  Obviously, the point will not be `touched'.   */
1888   /*                                                                       */
1889   /* <Input>                                                               */
1890   /*    point    :: The index of the point to move.                        */
1891   /*                                                                       */
1892   /*    distance :: The distance to apply.                                 */
1893   /*                                                                       */
1894   /* <InOut>                                                               */
1895   /*    zone     :: The affected glyph zone.                               */
1896   /*                                                                       */
1897   static void
1898   Direct_Move_Orig( EXEC_OP_ TT_GlyphZone  zone,
1899                              FT_UShort     point,
1900                              FT_F26Dot6    distance )
1901   {
1902     FT_F26Dot6  v;
1903
1904
1905 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1906     FT_ASSERT( !CUR.face->unpatented_hinting );
1907 #endif
1908
1909     v = CUR.GS.freeVector.x;
1910
1911     if ( v != 0 )
1912       zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
1913
1914     v = CUR.GS.freeVector.y;
1915
1916     if ( v != 0 )
1917       zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
1918   }
1919
1920
1921   /*************************************************************************/
1922   /*                                                                       */
1923   /* Special versions of Direct_Move()                                     */
1924   /*                                                                       */
1925   /*   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. */
1927   /*                                                                       */
1928   /*************************************************************************/
1929
1930
1931   static void
1932   Direct_Move_X( EXEC_OP_ TT_GlyphZone  zone,
1933                           FT_UShort     point,
1934                           FT_F26Dot6    distance )
1935   {
1936     FT_UNUSED_EXEC;
1937
1938 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1939     if ( !SUBPIXEL_HINTING  ||
1940          !CUR.ignore_x_mode )
1941 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1942       zone->cur[point].x += distance;
1943
1944     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_X;
1945   }
1946
1947
1948   static void
1949   Direct_Move_Y( EXEC_OP_ TT_GlyphZone  zone,
1950                           FT_UShort     point,
1951                           FT_F26Dot6    distance )
1952   {
1953     FT_UNUSED_EXEC;
1954
1955     zone->cur[point].y += distance;
1956     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
1957   }
1958
1959
1960   /*************************************************************************/
1961   /*                                                                       */
1962   /* Special versions of Direct_Move_Orig()                                */
1963   /*                                                                       */
1964   /*   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. */
1966   /*                                                                       */
1967   /*************************************************************************/
1968
1969
1970   static void
1971   Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone  zone,
1972                                FT_UShort     point,
1973                                FT_F26Dot6    distance )
1974   {
1975     FT_UNUSED_EXEC;
1976
1977     zone->org[point].x += distance;
1978   }
1979
1980
1981   static void
1982   Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone  zone,
1983                                FT_UShort     point,
1984                                FT_F26Dot6    distance )
1985   {
1986     FT_UNUSED_EXEC;
1987
1988     zone->org[point].y += distance;
1989   }
1990
1991
1992   /*************************************************************************/
1993   /*                                                                       */
1994   /* <Function>                                                            */
1995   /*    Round_None                                                         */
1996   /*                                                                       */
1997   /* <Description>                                                         */
1998   /*    Does not round, but adds engine compensation.                      */
1999   /*                                                                       */
2000   /* <Input>                                                               */
2001   /*    distance     :: The distance (not) to round.                       */
2002   /*                                                                       */
2003   /*    compensation :: The engine compensation.                           */
2004   /*                                                                       */
2005   /* <Return>                                                              */
2006   /*    The compensated distance.                                          */
2007   /*                                                                       */
2008   /* <Note>                                                                */
2009   /*    The TrueType specification says very few about the relationship    */
2010   /*    between rounding and engine compensation.  However, it seems from  */
2011   /*    the description of super round that we should add the compensation */
2012   /*    before rounding.                                                   */
2013   /*                                                                       */
2014   static FT_F26Dot6
2015   Round_None( EXEC_OP_ FT_F26Dot6  distance,
2016                        FT_F26Dot6  compensation )
2017   {
2018     FT_F26Dot6  val;
2019
2020     FT_UNUSED_EXEC;
2021
2022
2023     if ( distance >= 0 )
2024     {
2025       val = distance + compensation;
2026       if ( val < 0 )
2027         val = 0;
2028     }
2029     else
2030     {
2031       val = distance - compensation;
2032       if ( val > 0 )
2033         val = 0;
2034     }
2035     return val;
2036   }
2037
2038
2039   /*************************************************************************/
2040   /*                                                                       */
2041   /* <Function>                                                            */
2042   /*    Round_To_Grid                                                      */
2043   /*                                                                       */
2044   /* <Description>                                                         */
2045   /*    Rounds value to grid after adding engine compensation.             */
2046   /*                                                                       */
2047   /* <Input>                                                               */
2048   /*    distance     :: The distance to round.                             */
2049   /*                                                                       */
2050   /*    compensation :: The engine compensation.                           */
2051   /*                                                                       */
2052   /* <Return>                                                              */
2053   /*    Rounded distance.                                                  */
2054   /*                                                                       */
2055   static FT_F26Dot6
2056   Round_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
2057                           FT_F26Dot6  compensation )
2058   {
2059     FT_F26Dot6  val;
2060
2061     FT_UNUSED_EXEC;
2062
2063
2064     if ( distance >= 0 )
2065     {
2066       val = FT_PIX_ROUND( distance + compensation );
2067       if ( val < 0 )
2068         val = 0;
2069     }
2070     else
2071     {
2072       val = -FT_PIX_ROUND( compensation - distance );
2073       if ( val > 0 )
2074         val = 0;
2075     }
2076
2077     return  val;
2078   }
2079
2080
2081   /*************************************************************************/
2082   /*                                                                       */
2083   /* <Function>                                                            */
2084   /*    Round_To_Half_Grid                                                 */
2085   /*                                                                       */
2086   /* <Description>                                                         */
2087   /*    Rounds value to half grid after adding engine compensation.        */
2088   /*                                                                       */
2089   /* <Input>                                                               */
2090   /*    distance     :: The distance to round.                             */
2091   /*                                                                       */
2092   /*    compensation :: The engine compensation.                           */
2093   /*                                                                       */
2094   /* <Return>                                                              */
2095   /*    Rounded distance.                                                  */
2096   /*                                                                       */
2097   static FT_F26Dot6
2098   Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6  distance,
2099                                FT_F26Dot6  compensation )
2100   {
2101     FT_F26Dot6  val;
2102
2103     FT_UNUSED_EXEC;
2104
2105
2106     if ( distance >= 0 )
2107     {
2108       val = FT_PIX_FLOOR( distance + compensation ) + 32;
2109       if ( val < 0 )
2110         val = 32;
2111     }
2112     else
2113     {
2114       val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
2115       if ( val > 0 )
2116         val = -32;
2117     }
2118
2119     return val;
2120   }
2121
2122
2123   /*************************************************************************/
2124   /*                                                                       */
2125   /* <Function>                                                            */
2126   /*    Round_Down_To_Grid                                                 */
2127   /*                                                                       */
2128   /* <Description>                                                         */
2129   /*    Rounds value down to grid after adding engine compensation.        */
2130   /*                                                                       */
2131   /* <Input>                                                               */
2132   /*    distance     :: The distance to round.                             */
2133   /*                                                                       */
2134   /*    compensation :: The engine compensation.                           */
2135   /*                                                                       */
2136   /* <Return>                                                              */
2137   /*    Rounded distance.                                                  */
2138   /*                                                                       */
2139   static FT_F26Dot6
2140   Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
2141                                FT_F26Dot6  compensation )
2142   {
2143     FT_F26Dot6  val;
2144
2145     FT_UNUSED_EXEC;
2146
2147
2148     if ( distance >= 0 )
2149     {
2150       val = FT_PIX_FLOOR( distance + compensation );
2151       if ( val < 0 )
2152         val = 0;
2153     }
2154     else
2155     {
2156       val = -FT_PIX_FLOOR( compensation - distance );
2157       if ( val > 0 )
2158         val = 0;
2159     }
2160
2161     return val;
2162   }
2163
2164
2165   /*************************************************************************/
2166   /*                                                                       */
2167   /* <Function>                                                            */
2168   /*    Round_Up_To_Grid                                                   */
2169   /*                                                                       */
2170   /* <Description>                                                         */
2171   /*    Rounds value up to grid after adding engine compensation.          */
2172   /*                                                                       */
2173   /* <Input>                                                               */
2174   /*    distance     :: The distance to round.                             */
2175   /*                                                                       */
2176   /*    compensation :: The engine compensation.                           */
2177   /*                                                                       */
2178   /* <Return>                                                              */
2179   /*    Rounded distance.                                                  */
2180   /*                                                                       */
2181   static FT_F26Dot6
2182   Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
2183                              FT_F26Dot6  compensation )
2184   {
2185     FT_F26Dot6  val;
2186
2187     FT_UNUSED_EXEC;
2188
2189
2190     if ( distance >= 0 )
2191     {
2192       val = FT_PIX_CEIL( distance + compensation );
2193       if ( val < 0 )
2194         val = 0;
2195     }
2196     else
2197     {
2198       val = -FT_PIX_CEIL( compensation - distance );
2199       if ( val > 0 )
2200         val = 0;
2201     }
2202
2203     return val;
2204   }
2205
2206
2207   /*************************************************************************/
2208   /*                                                                       */
2209   /* <Function>                                                            */
2210   /*    Round_To_Double_Grid                                               */
2211   /*                                                                       */
2212   /* <Description>                                                         */
2213   /*    Rounds value to double grid after adding engine compensation.      */
2214   /*                                                                       */
2215   /* <Input>                                                               */
2216   /*    distance     :: The distance to round.                             */
2217   /*                                                                       */
2218   /*    compensation :: The engine compensation.                           */
2219   /*                                                                       */
2220   /* <Return>                                                              */
2221   /*    Rounded distance.                                                  */
2222   /*                                                                       */
2223   static FT_F26Dot6
2224   Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6  distance,
2225                                  FT_F26Dot6  compensation )
2226   {
2227     FT_F26Dot6 val;
2228
2229     FT_UNUSED_EXEC;
2230
2231
2232     if ( distance >= 0 )
2233     {
2234       val = FT_PAD_ROUND( distance + compensation, 32 );
2235       if ( val < 0 )
2236         val = 0;
2237     }
2238     else
2239     {
2240       val = -FT_PAD_ROUND( compensation - distance, 32 );
2241       if ( val > 0 )
2242         val = 0;
2243     }
2244
2245     return val;
2246   }
2247
2248
2249   /*************************************************************************/
2250   /*                                                                       */
2251   /* <Function>                                                            */
2252   /*    Round_Super                                                        */
2253   /*                                                                       */
2254   /* <Description>                                                         */
2255   /*    Super-rounds value to grid after adding engine compensation.       */
2256   /*                                                                       */
2257   /* <Input>                                                               */
2258   /*    distance     :: The distance to round.                             */
2259   /*                                                                       */
2260   /*    compensation :: The engine compensation.                           */
2261   /*                                                                       */
2262   /* <Return>                                                              */
2263   /*    Rounded distance.                                                  */
2264   /*                                                                       */
2265   /* <Note>                                                                */
2266   /*    The TrueType specification says very few about the relationship    */
2267   /*    between rounding and engine compensation.  However, it seems from  */
2268   /*    the description of super round that we should add the compensation */
2269   /*    before rounding.                                                   */
2270   /*                                                                       */
2271   static FT_F26Dot6
2272   Round_Super( EXEC_OP_ FT_F26Dot6  distance,
2273                         FT_F26Dot6  compensation )
2274   {
2275     FT_F26Dot6  val;
2276
2277
2278     if ( distance >= 0 )
2279     {
2280       val = ( distance - CUR.phase + CUR.threshold + compensation ) &
2281               -CUR.period;
2282       val += CUR.phase;
2283       if ( val < 0 )
2284         val = CUR.phase;
2285     }
2286     else
2287     {
2288       val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
2289                -CUR.period );
2290       val -= CUR.phase;
2291       if ( val > 0 )
2292         val = -CUR.phase;
2293     }
2294
2295     return val;
2296   }
2297
2298
2299   /*************************************************************************/
2300   /*                                                                       */
2301   /* <Function>                                                            */
2302   /*    Round_Super_45                                                     */
2303   /*                                                                       */
2304   /* <Description>                                                         */
2305   /*    Super-rounds value to grid after adding engine compensation.       */
2306   /*                                                                       */
2307   /* <Input>                                                               */
2308   /*    distance     :: The distance to round.                             */
2309   /*                                                                       */
2310   /*    compensation :: The engine compensation.                           */
2311   /*                                                                       */
2312   /* <Return>                                                              */
2313   /*    Rounded distance.                                                  */
2314   /*                                                                       */
2315   /* <Note>                                                                */
2316   /*    There is a separate function for Round_Super_45() as we may need   */
2317   /*    greater precision.                                                 */
2318   /*                                                                       */
2319   static FT_F26Dot6
2320   Round_Super_45( EXEC_OP_ FT_F26Dot6  distance,
2321                            FT_F26Dot6  compensation )
2322   {
2323     FT_F26Dot6  val;
2324
2325
2326     if ( distance >= 0 )
2327     {
2328       val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
2329                 CUR.period ) * CUR.period;
2330       val += CUR.phase;
2331       if ( val < 0 )
2332         val = CUR.phase;
2333     }
2334     else
2335     {
2336       val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
2337                    CUR.period ) * CUR.period );
2338       val -= CUR.phase;
2339       if ( val > 0 )
2340         val = -CUR.phase;
2341     }
2342
2343     return val;
2344   }
2345
2346
2347   /*************************************************************************/
2348   /*                                                                       */
2349   /* <Function>                                                            */
2350   /*    Compute_Round                                                      */
2351   /*                                                                       */
2352   /* <Description>                                                         */
2353   /*    Sets the rounding mode.                                            */
2354   /*                                                                       */
2355   /* <Input>                                                               */
2356   /*    round_mode :: The rounding mode to be used.                        */
2357   /*                                                                       */
2358   static void
2359   Compute_Round( EXEC_OP_ FT_Byte  round_mode )
2360   {
2361     switch ( round_mode )
2362     {
2363     case TT_Round_Off:
2364       CUR.func_round = (TT_Round_Func)Round_None;
2365       break;
2366
2367     case TT_Round_To_Grid:
2368       CUR.func_round = (TT_Round_Func)Round_To_Grid;
2369       break;
2370
2371     case TT_Round_Up_To_Grid:
2372       CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
2373       break;
2374
2375     case TT_Round_Down_To_Grid:
2376       CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
2377       break;
2378
2379     case TT_Round_To_Half_Grid:
2380       CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
2381       break;
2382
2383     case TT_Round_To_Double_Grid:
2384       CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
2385       break;
2386
2387     case TT_Round_Super:
2388       CUR.func_round = (TT_Round_Func)Round_Super;
2389       break;
2390
2391     case TT_Round_Super_45:
2392       CUR.func_round = (TT_Round_Func)Round_Super_45;
2393       break;
2394     }
2395   }
2396
2397
2398   /*************************************************************************/
2399   /*                                                                       */
2400   /* <Function>                                                            */
2401   /*    SetSuperRound                                                      */
2402   /*                                                                       */
2403   /* <Description>                                                         */
2404   /*    Sets Super Round parameters.                                       */
2405   /*                                                                       */
2406   /* <Input>                                                               */
2407   /*    GridPeriod :: The grid period.                                     */
2408   /*                                                                       */
2409   /*    selector   :: The SROUND opcode.                                   */
2410   /*                                                                       */
2411   static void
2412   SetSuperRound( EXEC_OP_ FT_F26Dot6  GridPeriod,
2413                           FT_Long     selector )
2414   {
2415     switch ( (FT_Int)( selector & 0xC0 ) )
2416     {
2417       case 0:
2418         CUR.period = GridPeriod / 2;
2419         break;
2420
2421       case 0x40:
2422         CUR.period = GridPeriod;
2423         break;
2424
2425       case 0x80:
2426         CUR.period = GridPeriod * 2;
2427         break;
2428
2429       /* This opcode is reserved, but... */
2430
2431       case 0xC0:
2432         CUR.period = GridPeriod;
2433         break;
2434     }
2435
2436     switch ( (FT_Int)( selector & 0x30 ) )
2437     {
2438     case 0:
2439       CUR.phase = 0;
2440       break;
2441
2442     case 0x10:
2443       CUR.phase = CUR.period / 4;
2444       break;
2445
2446     case 0x20:
2447       CUR.phase = CUR.period / 2;
2448       break;
2449
2450     case 0x30:
2451       CUR.phase = CUR.period * 3 / 4;
2452       break;
2453     }
2454
2455     if ( ( selector & 0x0F ) == 0 )
2456       CUR.threshold = CUR.period - 1;
2457     else
2458       CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
2459
2460     CUR.period    /= 256;
2461     CUR.phase     /= 256;
2462     CUR.threshold /= 256;
2463   }
2464
2465
2466   /*************************************************************************/
2467   /*                                                                       */
2468   /* <Function>                                                            */
2469   /*    Project                                                            */
2470   /*                                                                       */
2471   /* <Description>                                                         */
2472   /*    Computes the projection of vector given by (v2-v1) along the       */
2473   /*    current projection vector.                                         */
2474   /*                                                                       */
2475   /* <Input>                                                               */
2476   /*    v1 :: First input vector.                                          */
2477   /*    v2 :: Second input vector.                                         */
2478   /*                                                                       */
2479   /* <Return>                                                              */
2480   /*    The distance in F26dot6 format.                                    */
2481   /*                                                                       */
2482   static FT_F26Dot6
2483   Project( EXEC_OP_ FT_Pos  dx,
2484                     FT_Pos  dy )
2485   {
2486 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2487     FT_ASSERT( !CUR.face->unpatented_hinting );
2488 #endif
2489
2490     return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
2491                         CUR.GS.projVector.x,
2492                         CUR.GS.projVector.y );
2493   }
2494
2495
2496   /*************************************************************************/
2497   /*                                                                       */
2498   /* <Function>                                                            */
2499   /*    Dual_Project                                                       */
2500   /*                                                                       */
2501   /* <Description>                                                         */
2502   /*    Computes the projection of the vector given by (v2-v1) along the   */
2503   /*    current dual vector.                                               */
2504   /*                                                                       */
2505   /* <Input>                                                               */
2506   /*    v1 :: First input vector.                                          */
2507   /*    v2 :: Second input vector.                                         */
2508   /*                                                                       */
2509   /* <Return>                                                              */
2510   /*    The distance in F26dot6 format.                                    */
2511   /*                                                                       */
2512   static FT_F26Dot6
2513   Dual_Project( EXEC_OP_ FT_Pos  dx,
2514                          FT_Pos  dy )
2515   {
2516     return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
2517                         CUR.GS.dualVector.x,
2518                         CUR.GS.dualVector.y );
2519   }
2520
2521
2522   /*************************************************************************/
2523   /*                                                                       */
2524   /* <Function>                                                            */
2525   /*    Project_x                                                          */
2526   /*                                                                       */
2527   /* <Description>                                                         */
2528   /*    Computes the projection of the vector given by (v2-v1) along the   */
2529   /*    horizontal axis.                                                   */
2530   /*                                                                       */
2531   /* <Input>                                                               */
2532   /*    v1 :: First input vector.                                          */
2533   /*    v2 :: Second input vector.                                         */
2534   /*                                                                       */
2535   /* <Return>                                                              */
2536   /*    The distance in F26dot6 format.                                    */
2537   /*                                                                       */
2538   static FT_F26Dot6
2539   Project_x( EXEC_OP_ FT_Pos  dx,
2540                       FT_Pos  dy )
2541   {
2542     FT_UNUSED_EXEC;
2543     FT_UNUSED( dy );
2544
2545     return dx;
2546   }
2547
2548
2549   /*************************************************************************/
2550   /*                                                                       */
2551   /* <Function>                                                            */
2552   /*    Project_y                                                          */
2553   /*                                                                       */
2554   /* <Description>                                                         */
2555   /*    Computes the projection of the vector given by (v2-v1) along the   */
2556   /*    vertical axis.                                                     */
2557   /*                                                                       */
2558   /* <Input>                                                               */
2559   /*    v1 :: First input vector.                                          */
2560   /*    v2 :: Second input vector.                                         */
2561   /*                                                                       */
2562   /* <Return>                                                              */
2563   /*    The distance in F26dot6 format.                                    */
2564   /*                                                                       */
2565   static FT_F26Dot6
2566   Project_y( EXEC_OP_ FT_Pos  dx,
2567                       FT_Pos  dy )
2568   {
2569     FT_UNUSED_EXEC;
2570     FT_UNUSED( dx );
2571
2572     return dy;
2573   }
2574
2575
2576   /*************************************************************************/
2577   /*                                                                       */
2578   /* <Function>                                                            */
2579   /*    Compute_Funcs                                                      */
2580   /*                                                                       */
2581   /* <Description>                                                         */
2582   /*    Computes the projection and movement function pointers according   */
2583   /*    to the current graphics state.                                     */
2584   /*                                                                       */
2585   static void
2586   Compute_Funcs( EXEC_OP )
2587   {
2588 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2589     if ( CUR.face->unpatented_hinting )
2590     {
2591       /* If both vectors point rightwards along the x axis, set             */
2592       /* `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    */
2594       /* vector of length 0x4000 = unity.                                   */
2595       CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
2596                                       CUR.GS.freeVector.x == 0x4000 );
2597
2598       /* Throw away projection and freedom vector information */
2599       /* because the patents don't allow them to be stored.   */
2600       /* The relevant US Patents are 5155805 and 5325479.     */
2601       CUR.GS.projVector.x = 0;
2602       CUR.GS.projVector.y = 0;
2603       CUR.GS.freeVector.x = 0;
2604       CUR.GS.freeVector.y = 0;
2605
2606       if ( CUR.GS.both_x_axis )
2607       {
2608         CUR.func_project   = Project_x;
2609         CUR.func_move      = Direct_Move_X;
2610         CUR.func_move_orig = Direct_Move_Orig_X;
2611       }
2612       else
2613       {
2614         CUR.func_project   = Project_y;
2615         CUR.func_move      = Direct_Move_Y;
2616         CUR.func_move_orig = Direct_Move_Orig_Y;
2617       }
2618
2619       if ( CUR.GS.dualVector.x == 0x4000 )
2620         CUR.func_dualproj = Project_x;
2621       else if ( CUR.GS.dualVector.y == 0x4000 )
2622         CUR.func_dualproj = Project_y;
2623       else
2624         CUR.func_dualproj = Dual_Project;
2625
2626       /* Force recalculation of cached aspect ratio */
2627       CUR.tt_metrics.ratio = 0;
2628
2629       return;
2630     }
2631 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
2632
2633     if ( CUR.GS.freeVector.x == 0x4000 )
2634       CUR.F_dot_P = CUR.GS.projVector.x;
2635     else if ( CUR.GS.freeVector.y == 0x4000 )
2636       CUR.F_dot_P = CUR.GS.projVector.y;
2637     else
2638       CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
2639                       (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
2640                     14;
2641
2642     if ( CUR.GS.projVector.x == 0x4000 )
2643       CUR.func_project = (TT_Project_Func)Project_x;
2644     else if ( CUR.GS.projVector.y == 0x4000 )
2645       CUR.func_project = (TT_Project_Func)Project_y;
2646     else
2647       CUR.func_project = (TT_Project_Func)Project;
2648
2649     if ( CUR.GS.dualVector.x == 0x4000 )
2650       CUR.func_dualproj = (TT_Project_Func)Project_x;
2651     else if ( CUR.GS.dualVector.y == 0x4000 )
2652       CUR.func_dualproj = (TT_Project_Func)Project_y;
2653     else
2654       CUR.func_dualproj = (TT_Project_Func)Dual_Project;
2655
2656     CUR.func_move      = (TT_Move_Func)Direct_Move;
2657     CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
2658
2659     if ( CUR.F_dot_P == 0x4000L )
2660     {
2661       if ( CUR.GS.freeVector.x == 0x4000 )
2662       {
2663         CUR.func_move      = (TT_Move_Func)Direct_Move_X;
2664         CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
2665       }
2666       else if ( CUR.GS.freeVector.y == 0x4000 )
2667       {
2668         CUR.func_move      = (TT_Move_Func)Direct_Move_Y;
2669         CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
2670       }
2671     }
2672
2673     /* at small sizes, F_dot_P can become too small, resulting   */
2674     /* in overflows and `spikes' in a number of glyphs like `w'. */
2675
2676     if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
2677       CUR.F_dot_P = 0x4000L;
2678
2679     /* Disable cached aspect ratio */
2680     CUR.tt_metrics.ratio = 0;
2681   }
2682
2683
2684   /*************************************************************************/
2685   /*                                                                       */
2686   /* <Function>                                                            */
2687   /*    Normalize                                                          */
2688   /*                                                                       */
2689   /* <Description>                                                         */
2690   /*    Norms a vector.                                                    */
2691   /*                                                                       */
2692   /* <Input>                                                               */
2693   /*    Vx :: The horizontal input vector coordinate.                      */
2694   /*    Vy :: The vertical input vector coordinate.                        */
2695   /*                                                                       */
2696   /* <Output>                                                              */
2697   /*    R  :: The normed unit vector.                                      */
2698   /*                                                                       */
2699   /* <Return>                                                              */
2700   /*    Returns FAILURE if a vector parameter is zero.                     */
2701   /*                                                                       */
2702   /* <Note>                                                                */
2703   /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */
2704   /*    R is undefined.                                                    */
2705   /*                                                                       */
2706   static FT_Bool
2707   Normalize( EXEC_OP_ FT_F26Dot6      Vx,
2708                       FT_F26Dot6      Vy,
2709                       FT_UnitVector*  R )
2710   {
2711     FT_F26Dot6  W;
2712
2713     FT_UNUSED_EXEC;
2714
2715
2716     if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L )
2717     {
2718       if ( Vx == 0 && Vy == 0 )
2719       {
2720         /* XXX: UNDOCUMENTED! It seems that it is possible to try   */
2721         /*      to normalize the vector (0,0).  Return immediately. */
2722         return SUCCESS;
2723       }
2724
2725       Vx *= 0x4000;
2726       Vy *= 0x4000;
2727     }
2728
2729     W = FT_Hypot( Vx, Vy );
2730
2731     R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
2732     R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
2733
2734     return SUCCESS;
2735   }
2736
2737
2738   /*************************************************************************/
2739   /*                                                                       */
2740   /* Here we start with the implementation of the various opcodes.         */
2741   /*                                                                       */
2742   /*************************************************************************/
2743
2744
2745   static FT_Bool
2746   Ins_SxVTL( EXEC_OP_ FT_UShort       aIdx1,
2747                       FT_UShort       aIdx2,
2748                       FT_Int          aOpc,
2749                       FT_UnitVector*  Vec )
2750   {
2751     FT_Long     A, B, C;
2752     FT_Vector*  p1;
2753     FT_Vector*  p2;
2754
2755
2756     if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
2757          BOUNDS( aIdx2, CUR.zp1.n_points ) )
2758     {
2759       if ( CUR.pedantic_hinting )
2760         CUR.error = FT_THROW( Invalid_Reference );
2761       return FAILURE;
2762     }
2763
2764     p1 = CUR.zp1.cur + aIdx2;
2765     p2 = CUR.zp2.cur + aIdx1;
2766
2767     A = p1->x - p2->x;
2768     B = p1->y - p2->y;
2769
2770     /* If p1 == p2, SPVTL and SFVTL behave the same as */
2771     /* SPVTCA[X] and SFVTCA[X], respectively.          */
2772     /*                                                 */
2773     /* Confirmed by Greg Hitchcock.                    */
2774
2775     if ( A == 0 && B == 0 )
2776     {
2777       A    = 0x4000;
2778       aOpc = 0;
2779     }
2780
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],            &n