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