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 | |