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