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