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