• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * ttinterp.h
4  *
5  *   TrueType bytecode interpreter (specification).
6  *
7  * Copyright (C) 1996-2019 by
8  * 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 #ifndef TTINTERP_H_
20 #define TTINTERP_H_
21 
22 #include <ft2build.h>
23 #include "ttobjs.h"
24 
25 
26 FT_BEGIN_HEADER
27 
28 
29   /**************************************************************************
30    *
31    * Rounding mode constants.
32    */
33 #define TT_Round_Off             5
34 #define TT_Round_To_Half_Grid    0
35 #define TT_Round_To_Grid         1
36 #define TT_Round_To_Double_Grid  2
37 #define TT_Round_Up_To_Grid      4
38 #define TT_Round_Down_To_Grid    3
39 #define TT_Round_Super           6
40 #define TT_Round_Super_45        7
41 
42 
43   /**************************************************************************
44    *
45    * Function types used by the interpreter, depending on various modes
46    * (e.g. the rounding mode, whether to render a vertical or horizontal
47    * line etc).
48    *
49    */
50 
51   /* Rounding function */
52   typedef FT_F26Dot6
53   (*TT_Round_Func)( TT_ExecContext  exc,
54                     FT_F26Dot6      distance,
55                     FT_F26Dot6      compensation );
56 
57   /* Point displacement along the freedom vector routine */
58   typedef void
59   (*TT_Move_Func)( TT_ExecContext  exc,
60                    TT_GlyphZone    zone,
61                    FT_UShort       point,
62                    FT_F26Dot6      distance );
63 
64   /* Distance projection along one of the projection vectors */
65   typedef FT_F26Dot6
66   (*TT_Project_Func)( TT_ExecContext  exc,
67                       FT_Pos          dx,
68                       FT_Pos          dy );
69 
70   /* getting current ppem.  Take care of non-square pixels if necessary */
71   typedef FT_Long
72   (*TT_Cur_Ppem_Func)( TT_ExecContext  exc );
73 
74   /* reading a cvt value.  Take care of non-square pixels if necessary */
75   typedef FT_F26Dot6
76   (*TT_Get_CVT_Func)( TT_ExecContext  exc,
77                       FT_ULong        idx );
78 
79   /* setting or moving a cvt value.  Take care of non-square pixels  */
80   /* if necessary                                                    */
81   typedef void
82   (*TT_Set_CVT_Func)( TT_ExecContext  exc,
83                       FT_ULong        idx,
84                       FT_F26Dot6      value );
85 
86 
87   /**************************************************************************
88    *
89    * This structure defines a call record, used to manage function calls.
90    */
91   typedef struct  TT_CallRec_
92   {
93     FT_Int   Caller_Range;
94     FT_Long  Caller_IP;
95     FT_Long  Cur_Count;
96 
97     TT_DefRecord  *Def; /* either FDEF or IDEF */
98 
99   } TT_CallRec, *TT_CallStack;
100 
101 
102 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
103 
104   /**************************************************************************
105    *
106    * These structures define rules used to tweak subpixel hinting for
107    * various fonts.  "", 0, "", NULL value indicates to match any value.
108    */
109 
110 #define SPH_MAX_NAME_SIZE      32
111 #define SPH_MAX_CLASS_MEMBERS  100
112 
113   typedef struct  SPH_TweakRule_
114   {
115     const char      family[SPH_MAX_NAME_SIZE];
116     const FT_UInt   ppem;
117     const char      style[SPH_MAX_NAME_SIZE];
118     const FT_ULong  glyph;
119 
120   } SPH_TweakRule;
121 
122 
123   typedef struct  SPH_ScaleRule_
124   {
125     const char      family[SPH_MAX_NAME_SIZE];
126     const FT_UInt   ppem;
127     const char      style[SPH_MAX_NAME_SIZE];
128     const FT_ULong  glyph;
129     const FT_ULong  scale;
130 
131   } SPH_ScaleRule;
132 
133 
134   typedef struct  SPH_Font_Class_
135   {
136     const char  name[SPH_MAX_NAME_SIZE];
137     const char  member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE];
138 
139   } SPH_Font_Class;
140 
141 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
142 
143 
144   /**************************************************************************
145    *
146    * The main structure for the interpreter which collects all necessary
147    * variables and states.
148    */
149   typedef struct  TT_ExecContextRec_
150   {
151     TT_Face            face;
152     TT_Size            size;
153     FT_Memory          memory;
154 
155     /* instructions state */
156 
157     FT_Error           error;      /* last execution error */
158 
159     FT_Long            top;        /* top of exec. stack   */
160 
161     FT_Long            stackSize;  /* size of exec. stack  */
162     FT_Long*           stack;      /* current exec. stack  */
163 
164     FT_Long            args;
165     FT_Long            new_top;    /* new top after exec.  */
166 
167     TT_GlyphZoneRec    zp0,        /* zone records */
168                        zp1,
169                        zp2,
170                        pts,
171                        twilight;
172 
173     FT_Long            pointSize;  /* in 26.6 format */
174     FT_Size_Metrics    metrics;
175     TT_Size_Metrics    tt_metrics; /* size metrics */
176 
177     TT_GraphicsState   GS;         /* current graphics state */
178 
179     FT_Int             curRange;  /* current code range number   */
180     FT_Byte*           code;      /* current code range          */
181     FT_Long            IP;        /* current instruction pointer */
182     FT_Long            codeSize;  /* size of current range       */
183 
184     FT_Byte            opcode;    /* current opcode              */
185     FT_Int             length;    /* length of current opcode    */
186 
187     FT_Bool            step_ins;  /* true if the interpreter must */
188                                   /* increment IP after ins. exec */
189     FT_ULong           cvtSize;
190     FT_Long*           cvt;
191 
192     FT_UInt            glyphSize; /* glyph instructions buffer size */
193     FT_Byte*           glyphIns;  /* glyph instructions buffer */
194 
195     FT_UInt            numFDefs;  /* number of function defs         */
196     FT_UInt            maxFDefs;  /* maximum number of function defs */
197     TT_DefArray        FDefs;     /* table of FDefs entries          */
198 
199     FT_UInt            numIDefs;  /* number of instruction defs */
200     FT_UInt            maxIDefs;  /* maximum number of ins defs */
201     TT_DefArray        IDefs;     /* table of IDefs entries     */
202 
203     FT_UInt            maxFunc;   /* maximum function index     */
204     FT_UInt            maxIns;    /* maximum instruction index  */
205 
206     FT_Int             callTop,    /* top of call stack during execution */
207                        callSize;   /* size of call stack */
208     TT_CallStack       callStack;  /* call stack */
209 
210     FT_UShort          maxPoints;    /* capacity of this context's `pts' */
211     FT_Short           maxContours;  /* record, expressed in points and  */
212                                      /* contours.                        */
213 
214     TT_CodeRangeTable  codeRangeTable;  /* table of valid code ranges */
215                                         /* useful for the debugger   */
216 
217     FT_UShort          storeSize;  /* size of current storage */
218     FT_Long*           storage;    /* storage area            */
219 
220     FT_F26Dot6         period;     /* values used for the */
221     FT_F26Dot6         phase;      /* `SuperRounding'     */
222     FT_F26Dot6         threshold;
223 
224     FT_Bool            instruction_trap; /* If `True', the interpreter will */
225                                          /* exit after each instruction     */
226 
227     TT_GraphicsState   default_GS;       /* graphics state resulting from   */
228                                          /* the prep program                */
229     FT_Bool            is_composite;     /* true if the glyph is composite  */
230     FT_Bool            pedantic_hinting; /* true if pedantic interpretation */
231 
232     /* latest interpreter additions */
233 
234     FT_Long            F_dot_P;    /* dot product of freedom and projection */
235                                    /* vectors                               */
236     TT_Round_Func      func_round; /* current rounding function             */
237 
238     TT_Project_Func    func_project,   /* current projection function */
239                        func_dualproj,  /* current dual proj. function */
240                        func_freeProj;  /* current freedom proj. func  */
241 
242     TT_Move_Func       func_move;      /* current point move function */
243     TT_Move_Func       func_move_orig; /* move original position function */
244 
245     TT_Cur_Ppem_Func   func_cur_ppem;  /* get current proj. ppem value  */
246 
247     TT_Get_CVT_Func    func_read_cvt;  /* read a cvt entry              */
248     TT_Set_CVT_Func    func_write_cvt; /* write a cvt entry (in pixels) */
249     TT_Set_CVT_Func    func_move_cvt;  /* incr a cvt entry (in pixels)  */
250 
251     FT_Bool            grayscale;      /* bi-level hinting and */
252                                        /* grayscale rendering  */
253 
254 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
255     /*
256      * FreeType supports ClearType-like hinting of TrueType fonts through
257      * the version 40 interpreter.  This is achieved through several hacks
258      * in the base (v35) interpreter, as detailed below.
259      *
260      * ClearType is an umbrella term for several rendering techniques
261      * employed by Microsoft's various GUI and rendering toolkit
262      * implementations, most importantly: subpixel rendering for using the
263      * RGB subpixels of LCDs to approximately triple the perceived
264      * resolution on the x-axis and subpixel hinting for positioning stems
265      * on subpixel borders.  TrueType programming is explicit, i.e., fonts
266      * must be programmed to take advantage of ClearType's possibilities.
267      *
268      * When ClearType was introduced, it seemed unlikely that all fonts
269      * would be reprogrammed, so Microsoft decided to implement a backward
270      * compatibility mode.  It employs several simple to complicated
271      * assumptions and tricks, many of them font-dependent, that modify the
272      * interpretation of the bytecode contained in these fonts to retrofit
273      * them into a ClearType-y look.  The quality of the results varies.
274      * Most (web)fonts that were released since then have come to rely on
275      * these hacks to render correctly, even some of Microsoft's flagship
276      * fonts (e.g., Calibri, Cambria, Segoe UI).
277      *
278      * FreeType's minimal subpixel hinting code (interpreter version 40)
279      * employs a small list of font-agnostic hacks loosely based on the
280      * public information available on Microsoft's compatibility mode[2].
281      * The focus is on modern (web)fonts rather than legacy fonts that were
282      * made for monochrome rendering.  It will not match ClearType rendering
283      * exactly.  Unlike the `Infinality' code (interpreter version 38) that
284      * came before, it will not try to toggle hacks for specific fonts for
285      * performance and complexity reasons.  It will fall back to version 35
286      * behavior for tricky fonts[1] or when monochrome rendering is
287      * requested.
288      *
289      * Major hacks
290      *
291      * - Any point movement on the x axis is ignored (cf. `Direct_Move' and
292      *   `Direct_Move_X').  This has the smallest code footprint and single
293      *   biggest effect.  The ClearType way to increase resolution is
294      *   supersampling the x axis, the FreeType way is ignoring instructions
295      *   on the x axis, which gives the same result in the majority of
296      *   cases.
297      *
298      * - Points are not moved post-IUP (neither on the x nor on the y axis),
299      *   except the x component of diagonal moves post-IUP (cf.
300      *   `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point').  Post-IUP
301      *   changes are commonly used to `fix' pixel patterns which has little
302      *   use outside monochrome rendering.
303      *
304      * - SHPIX and DELTAP don't execute unless moving a composite on the
305      *   y axis or moving a previously y touched point.  SHPIX additionally
306      *   denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP').
307      *   Both instructions are commonly used to `fix' pixel patterns for
308      *   monochrome or Windows's GDI rendering but make little sense for
309      *   FreeType rendering.  Both can distort the outline.  See [2] for
310      *   details.
311      *
312      * - The hdmx table and modifications to phantom points are ignored.
313      *   Bearings and advance widths remain unchanged (except rounding them
314      *   outside the interpreter!), cf. `compute_glyph_metrics' and
315      *   `TT_Hint_Glyph'.  Letting non-native-ClearType fonts modify spacing
316      *   might mess up spacing.
317      *
318      * Minor hacks
319      *
320      * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP.  This
321      *   prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at
322      *   various sizes.
323      *
324      * (Post-IUP is the state after both IUP[x] and IUP[y] have been
325      * executed.)
326      *
327      * The best results are achieved for fonts that were from the outset
328      * designed with ClearType in mind, meaning they leave the x axis mostly
329      * alone and don't mess with the `final' outline to produce more
330      * pleasing pixel patterns.  The harder the designer tried to produce
331      * very specific patterns (`superhinting') for pre-ClearType-displays,
332      * the worse the results.
333      *
334      * Microsoft defines a way to turn off backward compatibility and
335      * interpret instructions as before (called `native ClearType')[2][3].
336      * The font designer then regains full control and is responsible for
337      * making the font work correctly with ClearType without any
338      * hand-holding by the interpreter or rasterizer[4].  The v40
339      * interpreter assumes backward compatibility by default, which can be
340      * turned off the same way by executing the following in the control
341      * program (cf. `Ins_INSTCTRL').
342      *
343      *   #PUSH 4,3
344      *   INSTCTRL[]
345      *
346      * [1] Tricky fonts as FreeType defines them rely on the bytecode
347      *     interpreter to display correctly.  Hacks can interfere with them,
348      *     so they get treated like native ClearType fonts (v40 with
349      *     backward compatibility turned off).  Cf. `TT_RunIns'.
350      *
351      * [2] Proposed by Microsoft's Greg Hitchcock in
352      *     https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
353      *
354      * [3] Beat Stamm describes it in more detail:
355      *     http://rastertragedy.com/RTRCh4.htm#Sec12.
356      *
357      * [4] The list of `native ClearType' fonts is small at the time of this
358      *     writing; I found the following on a Windows 10 Update 1511
359      *     installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft
360      *     JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold),
361      *     SimSun, NSimSun, and Yu Gothic.
362      *
363      */
364 
365     /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been
366      * requested.  Used to detect interpreter */
367     /* version switches.  `_lean' to differentiate from the Infinality */
368     /* `subpixel_hinting', which is managed differently.               */
369     FT_Bool            subpixel_hinting_lean;
370 
371     /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
372     /* `_lean' to differentiate from the Infinality `vertical_lcd', which */
373     /* is managed differently.                                            */
374     FT_Bool            vertical_lcd_lean;
375 
376     /* Default to backward compatibility mode in v40 interpreter.  If   */
377     /* this is false, it implies the interpreter is in v35 or in native */
378     /* ClearType mode.                                                  */
379     FT_Bool            backward_compatibility;
380 
381     /* Useful for detecting and denying post-IUP trickery that is usually */
382     /* used to fix pixel patterns (`superhinting').                       */
383     FT_Bool            iupx_called;
384     FT_Bool            iupy_called;
385 
386     /* ClearType hinting and grayscale rendering, as used by Universal */
387     /* Windows Platform apps (Windows 8 and above).  Like the standard */
388     /* colorful ClearType mode, it utilizes a vastly increased virtual */
389     /* resolution on the x axis.  Different from bi-level hinting and  */
390     /* grayscale rendering, the old mode from Win9x days that roughly  */
391     /* adheres to the physical pixel grid on both axes.                */
392     FT_Bool            grayscale_cleartype;
393 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
394 
395 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
396     TT_Round_Func      func_round_sphn;   /* subpixel rounding function */
397 
398     FT_Bool            subpixel_hinting;  /* Using subpixel hinting?       */
399     FT_Bool            ignore_x_mode;     /* Standard rendering mode for   */
400                                           /* subpixel hinting.  On if gray */
401                                           /* or subpixel hinting is on.    */
402 
403     /* The following 6 aren't fully implemented but here for MS rasterizer */
404     /* compatibility.                                                      */
405     FT_Bool            compatible_widths;     /* compatible widths?        */
406     FT_Bool            symmetrical_smoothing; /* symmetrical_smoothing?    */
407     FT_Bool            bgr;                   /* bgr instead of rgb?       */
408     FT_Bool            vertical_lcd;          /* long side of LCD subpixel */
409                                               /* rectangles is horizontal  */
410     FT_Bool            subpixel_positioned;   /* subpixel positioned       */
411                                               /* (DirectWrite ClearType)?  */
412     FT_Bool            gray_cleartype;        /* ClearType hinting but     */
413                                               /* grayscale rendering       */
414 
415     FT_Int             rasterizer_version;    /* MS rasterizer version     */
416 
417     FT_Bool            iup_called;            /* IUP called for glyph?     */
418 
419     FT_ULong           sph_tweak_flags;       /* flags to control          */
420                                               /* hint tweaks               */
421 
422     FT_ULong           sph_in_func_flags;     /* flags to indicate if in   */
423                                               /* special functions         */
424 
425 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
426 
427     /* We maintain two counters (in addition to the instruction counter) */
428     /* that act as loop detectors for LOOPCALL and jump opcodes with     */
429     /* negative arguments.                                               */
430     FT_ULong           loopcall_counter;
431     FT_ULong           loopcall_counter_max;
432     FT_ULong           neg_jump_counter;
433     FT_ULong           neg_jump_counter_max;
434 
435   } TT_ExecContextRec;
436 
437 
438   extern const TT_GraphicsState  tt_default_graphics_state;
439 
440 
441 #ifdef TT_USE_BYTECODE_INTERPRETER
442   FT_LOCAL( void )
443   TT_Goto_CodeRange( TT_ExecContext  exec,
444                      FT_Int          range,
445                      FT_Long         IP );
446 
447   FT_LOCAL( void )
448   TT_Set_CodeRange( TT_ExecContext  exec,
449                     FT_Int          range,
450                     void*           base,
451                     FT_Long         length );
452 
453   FT_LOCAL( void )
454   TT_Clear_CodeRange( TT_ExecContext  exec,
455                       FT_Int          range );
456 
457 
458   FT_LOCAL( FT_Error )
459   Update_Max( FT_Memory  memory,
460               FT_ULong*  size,
461               FT_ULong   multiplier,
462               void*      _pbuff,
463               FT_ULong   new_max );
464 #endif /* TT_USE_BYTECODE_INTERPRETER */
465 
466 
467   /**************************************************************************
468    *
469    * @Function:
470    *   TT_New_Context
471    *
472    * @Description:
473    *   Queries the face context for a given font.  Note that there is
474    *   now a _single_ execution context in the TrueType driver which is
475    *   shared among faces.
476    *
477    * @Input:
478    *   face ::
479    *     A handle to the source face object.
480    *
481    * @Return:
482    *   A handle to the execution context.  Initialized for `face'.
483    *
484    * @Note:
485    *   Only the glyph loader and debugger should call this function.
486    *   (And right now only the glyph loader uses it.)
487    */
488   FT_EXPORT( TT_ExecContext )
489   TT_New_Context( TT_Driver  driver );
490 
491 
492 #ifdef TT_USE_BYTECODE_INTERPRETER
493   FT_LOCAL( void )
494   TT_Done_Context( TT_ExecContext  exec );
495 
496   FT_LOCAL( FT_Error )
497   TT_Load_Context( TT_ExecContext  exec,
498                    TT_Face         face,
499                    TT_Size         size );
500 
501   FT_LOCAL( void )
502   TT_Save_Context( TT_ExecContext  exec,
503                    TT_Size         ins );
504 
505   FT_LOCAL( FT_Error )
506   TT_Run_Context( TT_ExecContext  exec );
507 #endif /* TT_USE_BYTECODE_INTERPRETER */
508 
509 
510   /**************************************************************************
511    *
512    * @Function:
513    *   TT_RunIns
514    *
515    * @Description:
516    *   Executes one or more instruction in the execution context.  This
517    *   is the main function of the TrueType opcode interpreter.
518    *
519    * @Input:
520    *   exec ::
521    *     A handle to the target execution context.
522    *
523    * @Return:
524    *   FreeType error code.  0 means success.
525    *
526    * @Note:
527    *   Only the object manager and debugger should call this function.
528    *
529    *   This function is publicly exported because it is directly
530    *   invoked by the TrueType debugger.
531    */
532   FT_EXPORT( FT_Error )
533   TT_RunIns( TT_ExecContext  exec );
534 
535 
536 FT_END_HEADER
537 
538 #endif /* TTINTERP_H_ */
539 
540 
541 /* END */
542