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