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