1 /***************************************************************************/ 2 /* */ 3 /* ttinterp.h */ 4 /* */ 5 /* TrueType bytecode interpreter (specification). */ 6 /* */ 7 /* Copyright 1996-2016 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 * Modern TrueType fonts are usually rendered through Microsoft's 257 * collection of rendering techniques called ClearType (e.g., subpixel 258 * rendering and subpixel hinting). When ClearType was introduced, most 259 * fonts were not ready. Microsoft decided to implement a backwards 260 * compatibility mode that employed several simple to complicated 261 * assumptions and tricks that modified the interpretation of the 262 * bytecode contained in these fonts to make them look ClearType-y 263 * somehow. Most (web)fonts that were released since then have come to 264 * rely on these hacks to render correctly, even some of Microsoft's 265 * flagship ClearType fonts (Calibri, Cambria, Segoe UI). 266 * 267 * The minimal subpixel hinting code (interpreter version 40) employs a 268 * small list of font-agnostic hacks to bludgeon non-native-ClearType 269 * fonts (except tricky ones[1]) into submission. It will not try to 270 * toggle hacks for specific fonts for performance and complexity 271 * reasons. The focus is on modern (web)fonts rather than legacy fonts 272 * that were made for black-and-white rendering. 273 * 274 * Major hacks 275 * 276 * - Any point movement on the x axis is ignored (cf. `Direct_Move' and 277 * `Direct_Move_X'). This has the smallest code footprint and single 278 * biggest effect. The ClearType way to increase resolution is 279 * supersampling the x axis, the FreeType way is ignoring instructions 280 * on the x axis, which gives the same result in the majority of 281 * cases. 282 * 283 * - Points are not moved post-IUP (neither on the x nor on the y axis), 284 * except the x component of diagonal moves post-IUP (cf. 285 * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP 286 * changes are commonly used to `fix' pixel patterns which has little 287 * use outside monochrome rendering. 288 * 289 * - SHPIX and DELTAP don't execute unless moving a composite on the 290 * y axis or moving a previously y touched point. SHPIX additionally 291 * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). 292 * Both instructions are commonly used to `fix' pixel patterns for 293 * monochrome or Windows's GDI rendering but make little sense for 294 * FreeType rendering. Both can distort the outline. See [2] for 295 * details. 296 * 297 * - The hdmx table and modifications to phantom points are ignored. 298 * Bearings and advance widths remain unchanged (except rounding them 299 * outside the interpreter!), cf. `compute_glyph_metrics' and 300 * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing 301 * might mess up spacing. 302 * 303 * Minor hacks 304 * 305 * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This 306 * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at 307 * various sizes. 308 * 309 * (Post-IUP is the state after both IUP[x] and IUP[y] have been 310 * executed.) 311 * 312 * The best results are achieved for fonts that were from the outset 313 * designed with ClearType in mind, meaning they leave the x axis mostly 314 * alone and don't mess with the `final' outline to produce more 315 * pleasing pixel patterns. The harder the designer tried to produce 316 * very specific patterns (`superhinting') for pre-ClearType-displays, 317 * the worse the results. 318 * 319 * Microsoft defines a way to turn off backwards compatibility and 320 * interpret instructions as before (called `native ClearType')[2][3]. 321 * The font designer then regains full control and is responsible for 322 * making the font work correctly with ClearType without any 323 * hand-holding by the interpreter or rasterizer[4]. The v40 324 * interpreter assumes backwards compatibility by default, which can be 325 * turned off the same way by executing the following in the control 326 * program (cf. `Ins_INSTCTRL'). 327 * 328 * #PUSH 4,3 329 * INSTCTRL[] 330 * 331 * [1] Tricky fonts as FreeType defines them rely on the bytecode 332 * interpreter to display correctly. Hacks can interfere with them, 333 * so they get treated like native ClearType fonts (v40 with 334 * backwards compatibility turned off). Cf. `TT_RunIns'. 335 * 336 * [2] Proposed by Microsoft's Greg Hitchcock in 337 * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx 338 * 339 * [3] Beat Stamm describes it in more detail: 340 * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 341 * 342 * [4] The list of `native ClearType' fonts is small at the time of this 343 * writing; I found the following on a Windows 10 Update 1511 344 * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft 345 * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), 346 * SimSun, NSimSun, and Yu Gothic. 347 * 348 */ 349 350 /* Using v40 implies subpixel hinting. Used to detect interpreter */ 351 /* version switches. `_lean' to differentiate from the Infinality */ 352 /* `subpixel_hinting', which is managed differently. */ 353 FT_Bool subpixel_hinting_lean; 354 355 /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ 356 /* `_lean' to differentiate from the Infinality `vertical_lcd', which */ 357 /* is managed differently. */ 358 FT_Bool vertical_lcd_lean; 359 360 /* Default to backwards compatibility mode in v40 interpreter. If */ 361 /* this is false, it implies the interpreter is in v35 or in native */ 362 /* ClearType mode. */ 363 FT_Bool backwards_compatibility; 364 365 /* Useful for detecting and denying post-IUP trickery that is usually */ 366 /* used to fix pixel patterns (`superhinting'). */ 367 FT_Bool iupx_called; 368 FT_Bool iupy_called; 369 370 /* ClearType hinting and grayscale rendering, as used by Universal */ 371 /* Windows Platform apps (Windows 8 and above). Like the standard */ 372 /* colorful ClearType mode, it utilizes a vastly increased virtual */ 373 /* resolution on the x axis. Different from bi-level hinting and */ 374 /* grayscale rendering, the old mode from Win9x days that roughly */ 375 /* adheres to the physical pixel grid on both axes. */ 376 FT_Bool grayscale_cleartype; 377 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ 378 379 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY 380 TT_Round_Func func_round_sphn; /* subpixel rounding function */ 381 382 FT_Bool subpixel_hinting; /* Using subpixel hinting? */ 383 FT_Bool ignore_x_mode; /* Standard rendering mode for */ 384 /* subpixel hinting. On if gray */ 385 /* or subpixel hinting is on. */ 386 387 /* The following 6 aren't fully implemented but here for MS rasterizer */ 388 /* compatibility. */ 389 FT_Bool compatible_widths; /* compatible widths? */ 390 FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ 391 FT_Bool bgr; /* bgr instead of rgb? */ 392 FT_Bool vertical_lcd; /* long side of LCD subpixel */ 393 /* rectangles is horizontal */ 394 FT_Bool subpixel_positioned; /* subpixel positioned */ 395 /* (DirectWrite ClearType)? */ 396 FT_Bool gray_cleartype; /* ClearType hinting but */ 397 /* grayscale rendering */ 398 399 FT_Int rasterizer_version; /* MS rasterizer version */ 400 401 FT_Bool iup_called; /* IUP called for glyph? */ 402 403 FT_ULong sph_tweak_flags; /* flags to control */ 404 /* hint tweaks */ 405 406 FT_ULong sph_in_func_flags; /* flags to indicate if in */ 407 /* special functions */ 408 409 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ 410 411 } TT_ExecContextRec; 412 413 414 extern const TT_GraphicsState tt_default_graphics_state; 415 416 417 #ifdef TT_USE_BYTECODE_INTERPRETER 418 FT_LOCAL( void ) 419 TT_Goto_CodeRange( TT_ExecContext exec, 420 FT_Int range, 421 FT_Long IP ); 422 423 FT_LOCAL( void ) 424 TT_Set_CodeRange( TT_ExecContext exec, 425 FT_Int range, 426 void* base, 427 FT_Long length ); 428 429 FT_LOCAL( void ) 430 TT_Clear_CodeRange( TT_ExecContext exec, 431 FT_Int range ); 432 433 434 FT_LOCAL( FT_Error ) 435 Update_Max( FT_Memory memory, 436 FT_ULong* size, 437 FT_ULong multiplier, 438 void* _pbuff, 439 FT_ULong new_max ); 440 #endif /* TT_USE_BYTECODE_INTERPRETER */ 441 442 443 /*************************************************************************/ 444 /* */ 445 /* <Function> */ 446 /* TT_New_Context */ 447 /* */ 448 /* <Description> */ 449 /* Queries the face context for a given font. Note that there is */ 450 /* now a _single_ execution context in the TrueType driver which is */ 451 /* shared among faces. */ 452 /* */ 453 /* <Input> */ 454 /* face :: A handle to the source face object. */ 455 /* */ 456 /* <Return> */ 457 /* A handle to the execution context. Initialized for `face'. */ 458 /* */ 459 /* <Note> */ 460 /* Only the glyph loader and debugger should call this function. */ 461 /* (And right now only the glyph loader uses it.) */ 462 /* */ 463 FT_EXPORT( TT_ExecContext ) 464 TT_New_Context( TT_Driver driver ); 465 466 467 #ifdef TT_USE_BYTECODE_INTERPRETER 468 FT_LOCAL( void ) 469 TT_Done_Context( TT_ExecContext exec ); 470 471 FT_LOCAL( FT_Error ) 472 TT_Load_Context( TT_ExecContext exec, 473 TT_Face face, 474 TT_Size size ); 475 476 FT_LOCAL( void ) 477 TT_Save_Context( TT_ExecContext exec, 478 TT_Size ins ); 479 480 FT_LOCAL( FT_Error ) 481 TT_Run_Context( TT_ExecContext exec ); 482 #endif /* TT_USE_BYTECODE_INTERPRETER */ 483 484 485 /*************************************************************************/ 486 /* */ 487 /* <Function> */ 488 /* TT_RunIns */ 489 /* */ 490 /* <Description> */ 491 /* Executes one or more instruction in the execution context. This */ 492 /* is the main function of the TrueType opcode interpreter. */ 493 /* */ 494 /* <Input> */ 495 /* exec :: A handle to the target execution context. */ 496 /* */ 497 /* <Return> */ 498 /* FreeType error code. 0 means success. */ 499 /* */ 500 /* <Note> */ 501 /* Only the object manager and debugger should call this function. */ 502 /* */ 503 /* This function is publicly exported because it is directly */ 504 /* invoked by the TrueType debugger. */ 505 /* */ 506 FT_EXPORT( FT_Error ) 507 TT_RunIns( TT_ExecContext exec ); 508 509 510 FT_END_HEADER 511 512 #endif /* TTINTERP_H_ */ 513 514 515 /* END */ 516