1 /**************************************************************************** 2 * 3 * aftypes.h 4 * 5 * Auto-fitter types (specification only). 6 * 7 * Copyright (C) 2003-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 /************************************************************************* 20 * 21 * The auto-fitter is a complete rewrite of the old auto-hinter. 22 * Its main feature is the ability to differentiate between different 23 * writing systems and scripts in order to apply specific rules. 24 * 25 * The code has also been compartmentalized into several entities that 26 * should make algorithmic experimentation easier than with the old 27 * code. 28 * 29 *************************************************************************/ 30 31 32 #ifndef AFTYPES_H_ 33 #define AFTYPES_H_ 34 35 36 #include <freetype/freetype.h> 37 #include <freetype/ftoutln.h> 38 #include <freetype/internal/ftobjs.h> 39 #include <freetype/internal/ftdebug.h> 40 41 #include "afblue.h" 42 43 #ifdef FT_DEBUG_AUTOFIT 44 #include FT_CONFIG_STANDARD_LIBRARY_H 45 #endif 46 47 48 FT_BEGIN_HEADER 49 50 /*************************************************************************/ 51 /*************************************************************************/ 52 /***** *****/ 53 /***** D E B U G G I N G *****/ 54 /***** *****/ 55 /*************************************************************************/ 56 /*************************************************************************/ 57 58 #ifdef FT_DEBUG_AUTOFIT 59 60 extern int _af_debug_disable_horz_hints; 61 extern int _af_debug_disable_vert_hints; 62 extern int _af_debug_disable_blue_hints; 63 extern void* _af_debug_hints; 64 65 #endif /* FT_DEBUG_AUTOFIT */ 66 67 68 /*************************************************************************/ 69 /*************************************************************************/ 70 /***** *****/ 71 /***** U T I L I T Y S T U F F *****/ 72 /***** *****/ 73 /*************************************************************************/ 74 /*************************************************************************/ 75 76 typedef struct AF_WidthRec_ 77 { 78 FT_Pos org; /* original position/width in font units */ 79 FT_Pos cur; /* current/scaled position/width in device subpixels */ 80 FT_Pos fit; /* current/fitted position/width in device subpixels */ 81 82 } AF_WidthRec, *AF_Width; 83 84 85 FT_LOCAL( void ) 86 af_sort_pos( FT_UInt count, 87 FT_Pos* table ); 88 89 FT_LOCAL( void ) 90 af_sort_and_quantize_widths( FT_UInt* count, 91 AF_Width widths, 92 FT_Pos threshold ); 93 94 95 /*************************************************************************/ 96 /*************************************************************************/ 97 /***** *****/ 98 /***** A N G L E T Y P E S *****/ 99 /***** *****/ 100 /*************************************************************************/ 101 /*************************************************************************/ 102 103 /* 104 * The auto-fitter doesn't need a very high angular accuracy; 105 * this allows us to speed up some computations considerably with a 106 * light Cordic algorithm (see afangles.c). 107 */ 108 109 typedef FT_Int AF_Angle; 110 111 112 #define AF_ANGLE_PI 256 113 #define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) 114 #define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) 115 #define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) 116 117 118 #if 0 119 /* 120 * compute the angle of a given 2-D vector 121 */ 122 FT_LOCAL( AF_Angle ) 123 af_angle_atan( FT_Pos dx, 124 FT_Pos dy ); 125 126 127 /* 128 * compute `angle2 - angle1'; the result is always within 129 * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] 130 */ 131 FT_LOCAL( AF_Angle ) 132 af_angle_diff( AF_Angle angle1, 133 AF_Angle angle2 ); 134 #endif /* 0 */ 135 136 137 #define AF_ANGLE_DIFF( result, angle1, angle2 ) \ 138 FT_BEGIN_STMNT \ 139 AF_Angle _delta = (angle2) - (angle1); \ 140 \ 141 \ 142 while ( _delta <= -AF_ANGLE_PI ) \ 143 _delta += AF_ANGLE_2PI; \ 144 \ 145 while ( _delta > AF_ANGLE_PI ) \ 146 _delta -= AF_ANGLE_2PI; \ 147 \ 148 result = _delta; \ 149 FT_END_STMNT 150 151 152 /* 153 * opaque handle to glyph-specific hints -- see `afhints.h' for more 154 * details 155 */ 156 typedef struct AF_GlyphHintsRec_* AF_GlyphHints; 157 158 159 /*************************************************************************/ 160 /*************************************************************************/ 161 /***** *****/ 162 /***** S C A L E R S *****/ 163 /***** *****/ 164 /*************************************************************************/ 165 /*************************************************************************/ 166 167 /* 168 * A scaler models the target pixel device that will receive the 169 * auto-hinted glyph image. 170 */ 171 172 #define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */ 173 #define AF_SCALER_FLAG_NO_VERTICAL 2U /* disable vertical hinting */ 174 #define AF_SCALER_FLAG_NO_ADVANCE 4U /* disable advance hinting */ 175 #define AF_SCALER_FLAG_NO_WARPER 8U /* disable warper */ 176 177 178 typedef struct AF_ScalerRec_ 179 { 180 FT_Face face; /* source font face */ 181 FT_Fixed x_scale; /* from font units to 1/64th device pixels */ 182 FT_Fixed y_scale; /* from font units to 1/64th device pixels */ 183 FT_Pos x_delta; /* in 1/64th device pixels */ 184 FT_Pos y_delta; /* in 1/64th device pixels */ 185 FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ 186 FT_UInt32 flags; /* additional control flags, see above */ 187 188 } AF_ScalerRec, *AF_Scaler; 189 190 191 #define AF_SCALER_EQUAL_SCALES( a, b ) \ 192 ( (a)->x_scale == (b)->x_scale && \ 193 (a)->y_scale == (b)->y_scale && \ 194 (a)->x_delta == (b)->x_delta && \ 195 (a)->y_delta == (b)->y_delta ) 196 197 198 typedef struct AF_StyleMetricsRec_* AF_StyleMetrics; 199 200 /* 201 * This function parses an FT_Face to compute global metrics for 202 * a specific style. 203 */ 204 typedef FT_Error 205 (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics metrics, 206 FT_Face face ); 207 208 typedef void 209 (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics metrics, 210 AF_Scaler scaler ); 211 212 typedef void 213 (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics metrics ); 214 215 typedef void 216 (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics metrics, 217 FT_Pos* stdHW, 218 FT_Pos* stdVW ); 219 220 221 typedef FT_Error 222 (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints hints, 223 AF_StyleMetrics metrics ); 224 225 typedef FT_Error 226 (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt glyph_index, 227 AF_GlyphHints hints, 228 FT_Outline* outline, 229 AF_StyleMetrics metrics ); 230 231 232 /*************************************************************************/ 233 /*************************************************************************/ 234 /***** *****/ 235 /***** W R I T I N G S Y S T E M S *****/ 236 /***** *****/ 237 /*************************************************************************/ 238 /*************************************************************************/ 239 240 /* 241 * For the auto-hinter, a writing system consists of multiple scripts that 242 * can be handled similarly *in a typographical way*; the relationship is 243 * not based on history. For example, both the Greek and the unrelated 244 * Armenian scripts share the same features like ascender, descender, 245 * x-height, etc. Essentially, a writing system is covered by a 246 * submodule of the auto-fitter; it contains 247 * 248 * - a specific global analyzer that computes global metrics specific to 249 * the script (based on script-specific characters to identify ascender 250 * height, x-height, etc.), 251 * 252 * - a specific glyph analyzer that computes segments and edges for each 253 * glyph covered by the script, 254 * 255 * - a specific grid-fitting algorithm that distorts the scaled glyph 256 * outline according to the results of the glyph analyzer. 257 */ 258 259 #define AFWRTSYS_H_ /* don't load header files */ 260 #undef WRITING_SYSTEM 261 #define WRITING_SYSTEM( ws, WS ) \ 262 AF_WRITING_SYSTEM_ ## WS, 263 264 /* The list of known writing systems. */ 265 typedef enum AF_WritingSystem_ 266 { 267 268 #include "afwrtsys.h" 269 270 AF_WRITING_SYSTEM_MAX /* do not remove */ 271 272 } AF_WritingSystem; 273 274 #undef AFWRTSYS_H_ 275 276 277 typedef struct AF_WritingSystemClassRec_ 278 { 279 AF_WritingSystem writing_system; 280 281 FT_Offset style_metrics_size; 282 AF_WritingSystem_InitMetricsFunc style_metrics_init; 283 AF_WritingSystem_ScaleMetricsFunc style_metrics_scale; 284 AF_WritingSystem_DoneMetricsFunc style_metrics_done; 285 AF_WritingSystem_GetStdWidthsFunc style_metrics_getstdw; 286 287 AF_WritingSystem_InitHintsFunc style_hints_init; 288 AF_WritingSystem_ApplyHintsFunc style_hints_apply; 289 290 } AF_WritingSystemClassRec; 291 292 typedef const AF_WritingSystemClassRec* AF_WritingSystemClass; 293 294 295 /*************************************************************************/ 296 /*************************************************************************/ 297 /***** *****/ 298 /***** S C R I P T S *****/ 299 /***** *****/ 300 /*************************************************************************/ 301 /*************************************************************************/ 302 303 /* 304 * Each script is associated with two sets of Unicode ranges to test 305 * whether the font face supports the script, and which non-base 306 * characters the script contains. 307 * 308 * We use four-letter script tags from the OpenType specification, 309 * extended by `NONE', which indicates `no script'. 310 */ 311 312 #undef SCRIPT 313 #define SCRIPT( s, S, d, h, H, ss ) \ 314 AF_SCRIPT_ ## S, 315 316 /* The list of known scripts. */ 317 typedef enum AF_Script_ 318 { 319 320 #include "afscript.h" 321 322 AF_SCRIPT_MAX /* do not remove */ 323 324 } AF_Script; 325 326 327 typedef struct AF_Script_UniRangeRec_ 328 { 329 FT_UInt32 first; 330 FT_UInt32 last; 331 332 } AF_Script_UniRangeRec; 333 334 #define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } 335 336 typedef const AF_Script_UniRangeRec* AF_Script_UniRange; 337 338 339 typedef struct AF_ScriptClassRec_ 340 { 341 AF_Script script; 342 343 /* last element in the ranges must be { 0, 0 } */ 344 AF_Script_UniRange script_uni_ranges; 345 AF_Script_UniRange script_uni_nonbase_ranges; 346 347 FT_Bool top_to_bottom_hinting; 348 349 const char* standard_charstring; /* for default width and height */ 350 351 } AF_ScriptClassRec; 352 353 typedef const AF_ScriptClassRec* AF_ScriptClass; 354 355 356 /*************************************************************************/ 357 /*************************************************************************/ 358 /***** *****/ 359 /***** C O V E R A G E S *****/ 360 /***** *****/ 361 /*************************************************************************/ 362 /*************************************************************************/ 363 364 /* 365 * Usually, a font contains more glyphs than can be addressed by its 366 * character map. 367 * 368 * In the PostScript font world, encoding vectors specific to a given 369 * task are used to select such glyphs, and these glyphs can be often 370 * recognized by having a suffix in its glyph names. For example, a 371 * superscript glyph `A' might be called `A.sup'. Unfortunately, this 372 * naming scheme is not standardized and thus unusable for us. 373 * 374 * In the OpenType world, a better solution was invented, namely 375 * `features', which cleanly separate a character's input encoding from 376 * the corresponding glyph's appearance, and which don't use glyph names 377 * at all. For our purposes, and slightly generalized, an OpenType 378 * feature is a name of a mapping that maps character codes to 379 * non-standard glyph indices (features get used for other things also). 380 * For example, the `sups' feature provides superscript glyphs, thus 381 * mapping character codes like `A' or `B' to superscript glyph 382 * representation forms. How this mapping happens is completely 383 * uninteresting to us. 384 * 385 * For the auto-hinter, a `coverage' represents all glyphs of an OpenType 386 * feature collected in a set (as listed below) that can be hinted 387 * together. To continue the above example, superscript glyphs must not 388 * be hinted together with normal glyphs because the blue zones 389 * completely differ. 390 * 391 * Note that FreeType itself doesn't compute coverages; it only provides 392 * the glyphs addressable by the default Unicode character map. Instead, 393 * we use the HarfBuzz library (if available), which has many functions 394 * exactly for this purpose. 395 * 396 * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't 397 * listed separately (including the glyphs addressable by the character 398 * map). In case HarfBuzz isn't available, it exactly covers the glyphs 399 * addressable by the character map. 400 * 401 */ 402 403 #undef COVERAGE 404 #define COVERAGE( name, NAME, description, \ 405 tag1, tag2, tag3, tag4 ) \ 406 AF_COVERAGE_ ## NAME, 407 408 409 typedef enum AF_Coverage_ 410 { 411 #include "afcover.h" 412 413 AF_COVERAGE_DEFAULT 414 415 } AF_Coverage; 416 417 418 /*************************************************************************/ 419 /*************************************************************************/ 420 /***** *****/ 421 /***** S T Y L E S *****/ 422 /***** *****/ 423 /*************************************************************************/ 424 /*************************************************************************/ 425 426 /* 427 * The topmost structure for modelling the auto-hinter glyph input data 428 * is a `style class', grouping everything together. 429 */ 430 431 #undef STYLE 432 #define STYLE( s, S, d, ws, sc, ss, c ) \ 433 AF_STYLE_ ## S, 434 435 /* The list of known styles. */ 436 typedef enum AF_Style_ 437 { 438 439 #include "afstyles.h" 440 441 AF_STYLE_MAX /* do not remove */ 442 443 } AF_Style; 444 445 446 typedef struct AF_StyleClassRec_ 447 { 448 AF_Style style; 449 450 AF_WritingSystem writing_system; 451 AF_Script script; 452 AF_Blue_Stringset blue_stringset; 453 AF_Coverage coverage; 454 455 } AF_StyleClassRec; 456 457 typedef const AF_StyleClassRec* AF_StyleClass; 458 459 460 /*************************************************************************/ 461 /*************************************************************************/ 462 /***** *****/ 463 /***** S T Y L E M E T R I C S *****/ 464 /***** *****/ 465 /*************************************************************************/ 466 /*************************************************************************/ 467 468 typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; 469 470 /* This is the main structure that combines everything. Autofit modules */ 471 /* specific to writing systems derive their structures from it, for */ 472 /* example `AF_LatinMetrics'. */ 473 474 typedef struct AF_StyleMetricsRec_ 475 { 476 AF_StyleClass style_class; 477 AF_ScalerRec scaler; 478 FT_Bool digits_have_same_width; 479 480 AF_FaceGlobals globals; /* to access properties */ 481 482 } AF_StyleMetricsRec; 483 484 485 #define AF_HINTING_BOTTOM_TO_TOP 0 486 #define AF_HINTING_TOP_TO_BOTTOM 1 487 488 489 /* Declare and define vtables for classes */ 490 #define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ 491 FT_CALLBACK_TABLE const AF_WritingSystemClassRec \ 492 writing_system_class; 493 494 #define AF_DEFINE_WRITING_SYSTEM_CLASS( \ 495 writing_system_class, \ 496 system, \ 497 m_size, \ 498 m_init, \ 499 m_scale, \ 500 m_done, \ 501 m_stdw, \ 502 h_init, \ 503 h_apply ) \ 504 FT_CALLBACK_TABLE_DEF \ 505 const AF_WritingSystemClassRec writing_system_class = \ 506 { \ 507 system, \ 508 \ 509 m_size, \ 510 \ 511 m_init, \ 512 m_scale, \ 513 m_done, \ 514 m_stdw, \ 515 \ 516 h_init, \ 517 h_apply \ 518 }; 519 520 521 #define AF_DECLARE_SCRIPT_CLASS( script_class ) \ 522 FT_CALLBACK_TABLE const AF_ScriptClassRec \ 523 script_class; 524 525 #define AF_DEFINE_SCRIPT_CLASS( \ 526 script_class, \ 527 script, \ 528 ranges, \ 529 nonbase_ranges, \ 530 top_to_bottom, \ 531 std_charstring ) \ 532 FT_CALLBACK_TABLE_DEF \ 533 const AF_ScriptClassRec script_class = \ 534 { \ 535 script, \ 536 ranges, \ 537 nonbase_ranges, \ 538 top_to_bottom, \ 539 std_charstring, \ 540 }; 541 542 543 #define AF_DECLARE_STYLE_CLASS( style_class ) \ 544 FT_CALLBACK_TABLE const AF_StyleClassRec \ 545 style_class; 546 547 #define AF_DEFINE_STYLE_CLASS( \ 548 style_class, \ 549 style, \ 550 writing_system, \ 551 script, \ 552 blue_stringset, \ 553 coverage ) \ 554 FT_CALLBACK_TABLE_DEF \ 555 const AF_StyleClassRec style_class = \ 556 { \ 557 style, \ 558 writing_system, \ 559 script, \ 560 blue_stringset, \ 561 coverage \ 562 }; 563 564 /* */ 565 566 567 FT_END_HEADER 568 569 #endif /* AFTYPES_H_ */ 570 571 572 /* END */ 573