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