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