sdk-world
v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Toggle main menu visibility
Loading...
Searching...
No Matches
afhints.h
Go to the documentation of this file.
1
/****************************************************************************
2
*
3
* afhints.h
4
*
5
* Auto-fitter hinting routines (specification).
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
23
#ifndef AFHINTS_H_
24
#define AFHINTS_H_
25
26
#include "
aftypes.h
"
27
28
FT_BEGIN_HEADER
29
30
/*
31
* The definition of outline glyph hints. These are shared by all
32
* writing system analysis routines (until now).
33
*/
34
35
typedef
enum
AF_Dimension_
36
{
37
AF_DIMENSION_HORZ = 0,
/* x coordinates, */
38
/* i.e., vertical segments & edges */
39
AF_DIMENSION_VERT = 1,
/* y coordinates, */
40
/* i.e., horizontal segments & edges */
41
42
AF_DIMENSION_MAX
/* do not remove */
43
44
} AF_Dimension;
45
46
47
/* hint directions -- the values are computed so that two vectors are */
48
/* in opposite directions iff `dir1 + dir2 == 0' */
49
typedef
enum
AF_Direction_
50
{
51
AF_DIR_NONE = 4,
52
AF_DIR_RIGHT = 1,
53
AF_DIR_LEFT = -1,
54
AF_DIR_UP = 2,
55
AF_DIR_DOWN = -2
56
57
} AF_Direction;
58
59
60
/*
61
* The following explanations are mostly taken from the article
62
*
63
* Real-Time Grid Fitting of Typographic Outlines
64
*
65
* by David Turner and Werner Lemberg
66
*
67
* https://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf
68
*
69
* with appropriate updates.
70
*
71
*
72
* Segments
73
*
74
* `af_{cjk,latin,...}_hints_compute_segments' are the functions to
75
* find segments in an outline.
76
*
77
* A segment is a series of at least two consecutive points that are
78
* approximately aligned along a coordinate axis. The analysis to do
79
* so is specific to a writing system.
80
*
81
*
82
* Edges
83
*
84
* `af_{cjk,latin,...}_hints_compute_edges' are the functions to find
85
* edges.
86
*
87
* As soon as segments are defined, the auto-hinter groups them into
88
* edges. An edge corresponds to a single position on the main
89
* dimension that collects one or more segments (allowing for a small
90
* threshold).
91
*
92
* As an example, the `latin' writing system first tries to grid-fit
93
* edges, then to align segments on the edges unless it detects that
94
* they form a serif.
95
*
96
*
97
* A H
98
* | |
99
* | |
100
* | |
101
* | |
102
* C | | F
103
* +------<-----+ +-----<------+
104
* | B G |
105
* | |
106
* | |
107
* +--------------->------------------+
108
* D E
109
*
110
*
111
* Stems
112
*
113
* Stems are detected by `af_{cjk,latin,...}_hint_edges'.
114
*
115
* Segments need to be `linked' to other ones in order to detect stems.
116
* A stem is made of two segments that face each other in opposite
117
* directions and that are sufficiently close to each other. Using
118
* vocabulary from the TrueType specification, stem segments form a
119
* `black distance'.
120
*
121
* In the above ASCII drawing, the horizontal segments are BC, DE, and
122
* FG; the vertical segments are AB, CD, EF, and GH.
123
*
124
* Each segment has at most one `best' candidate to form a black
125
* distance, or no candidate at all. Notice that two distinct segments
126
* can have the same candidate, which frequently means a serif.
127
*
128
* A stem is recognized by the following condition:
129
*
130
* best segment_1 = segment_2 && best segment_2 = segment_1
131
*
132
* The best candidate is stored in field `link' in structure
133
* `AF_Segment'.
134
*
135
* In the above ASCII drawing, the best candidate for both AB and CD is
136
* GH, while the best candidate for GH is AB. Similarly, the best
137
* candidate for EF and GH is AB, while the best candidate for AB is
138
* GH.
139
*
140
* The detection and handling of stems is dependent on the writing
141
* system.
142
*
143
*
144
* Serifs
145
*
146
* Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
147
*
148
* In comparison to a stem, a serif (as handled by the auto-hinter
149
* module that takes care of the `latin' writing system) has
150
*
151
* best segment_1 = segment_2 && best segment_2 != segment_1
152
*
153
* where segment_1 corresponds to the serif segment (CD and EF in the
154
* above ASCII drawing).
155
*
156
* The best candidate is stored in field `serif' in structure
157
* `AF_Segment' (and `link' is set to NULL).
158
*
159
*
160
* Touched points
161
*
162
* A point is called `touched' if it has been processed somehow by the
163
* auto-hinter. It basically means that it shouldn't be moved again
164
* (or moved only under certain constraints to preserve the already
165
* applied processing).
166
*
167
*
168
* Flat and round segments
169
*
170
* Segments are `round' or `flat', depending on the series of points
171
* that define them. A segment is round if the next and previous point
172
* of an extremum (which can be either a single point or sequence of
173
* points) are both conic or cubic control points. Otherwise, a
174
* segment with an extremum is flat.
175
*
176
*
177
* Strong Points
178
*
179
* Experience has shown that points not part of an edge need to be
180
* interpolated linearly between their two closest edges, even if these
181
* are not part of the contour of those particular points. Typical
182
* candidates for this are
183
*
184
* - angle points (i.e., points where the `in' and `out' direction
185
* differ greatly)
186
*
187
* - inflection points (i.e., where the `in' and `out' angles are the
188
* same, but the curvature changes sign) [currently, such points
189
* aren't handled specially in the auto-hinter]
190
*
191
* `af_glyph_hints_align_strong_points' is the function that takes
192
* care of such situations; it is equivalent to the TrueType `IP'
193
* hinting instruction.
194
*
195
*
196
* Weak Points
197
*
198
* Other points in the outline must be interpolated using the
199
* coordinates of their previous and next unfitted contour neighbours.
200
* These are called `weak points' and are touched by the function
201
* `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP'
202
* hinting instruction. Typical candidates are control points and
203
* points on the contour without a major direction.
204
*
205
* The major effect is to reduce possible distortion caused by
206
* alignment of edges and strong points, thus weak points are processed
207
* after strong points.
208
*/
209
210
211
/* point hint flags */
212
#define AF_FLAG_NONE 0
213
214
/* point type flags */
215
#define AF_FLAG_CONIC ( 1U << 0 )
216
#define AF_FLAG_CUBIC ( 1U << 1 )
217
#define AF_FLAG_CONTROL ( AF_FLAG_CONIC | AF_FLAG_CUBIC )
218
219
/* point touch flags */
220
#define AF_FLAG_TOUCH_X ( 1U << 2 )
221
#define AF_FLAG_TOUCH_Y ( 1U << 3 )
222
223
/* candidates for weak interpolation have this flag set */
224
#define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 )
225
226
/* the distance to the next point is very small */
227
#define AF_FLAG_NEAR ( 1U << 5 )
228
229
/* prevent the auto-hinter from adding such a point to a segment */
230
#define AF_FLAG_IGNORE ( 1U << 6 )
231
232
233
/* edge hint flags */
234
#define AF_EDGE_NORMAL 0
235
#define AF_EDGE_ROUND ( 1U << 0 )
236
#define AF_EDGE_SERIF ( 1U << 1 )
237
#define AF_EDGE_DONE ( 1U << 2 )
238
#define AF_EDGE_NEUTRAL ( 1U << 3 )
/* edge aligns to a neutral blue zone */
239
#define AF_EDGE_NO_BLUE ( 1U << 4 )
/* do not align edge to blue zone */
240
241
242
typedef
struct
AF_PointRec_
* AF_Point;
243
typedef
struct
AF_SegmentRec_
* AF_Segment;
244
typedef
struct
AF_EdgeRec_
* AF_Edge;
245
246
247
typedef
struct
AF_PointRec_
248
{
249
FT_UShort flags;
/* point flags used by hinter */
250
FT_Char in_dir;
/* direction of inwards vector */
251
FT_Char out_dir;
/* direction of outwards vector */
252
253
FT_Pos ox, oy;
/* original, scaled position */
254
FT_Short fx, fy;
/* original, unscaled position (in font units) */
255
FT_Pos x, y;
/* current position */
256
FT_Pos u, v;
/* current (x,y) or (y,x) depending on context */
257
258
AF_Point next;
/* next point in contour */
259
AF_Point prev;
/* previous point in contour */
260
261
#ifdef FT_DEBUG_AUTOFIT
262
/* track `before' and `after' edges for strong points */
263
AF_Edge before[2];
264
AF_Edge after[2];
265
#endif
266
267
} AF_PointRec;
268
269
270
typedef
struct
AF_SegmentRec_
271
{
272
FT_Byte flags;
/* edge/segment flags for this segment */
273
FT_Char dir;
/* segment direction */
274
FT_Short pos;
/* position of segment */
275
FT_Short delta;
/* deviation from segment position */
276
FT_Short min_coord;
/* minimum coordinate of segment */
277
FT_Short max_coord;
/* maximum coordinate of segment */
278
FT_Short height;
/* the hinted segment height */
279
280
AF_Edge edge;
/* the segment's parent edge */
281
AF_Segment edge_next;
/* link to next segment in parent edge */
282
283
AF_Segment link;
/* (stem) link segment */
284
AF_Segment serif;
/* primary segment for serifs */
285
FT_Pos score;
/* used during stem matching */
286
FT_Pos len;
/* used during stem matching */
287
288
AF_Point first;
/* first point in edge segment */
289
AF_Point last;
/* last point in edge segment */
290
291
} AF_SegmentRec;
292
293
294
typedef
struct
AF_EdgeRec_
295
{
296
FT_Short fpos;
/* original, unscaled position (in font units) */
297
FT_Pos opos;
/* original, scaled position */
298
FT_Pos pos;
/* current position */
299
300
FT_Byte flags;
/* edge flags */
301
FT_Char dir;
/* edge direction */
302
FT_Fixed scale;
/* used to speed up interpolation between edges */
303
304
AF_Width blue_edge;
/* non-NULL if this is a blue edge */
305
AF_Edge link;
/* link edge */
306
AF_Edge serif;
/* primary edge for serifs */
307
FT_Int score;
/* used during stem matching */
308
309
AF_Segment first;
/* first segment in edge */
310
AF_Segment last;
/* last segment in edge */
311
312
} AF_EdgeRec;
313
314
315
#define AF_SEGMENTS_EMBEDDED 18
/* number of embedded segments */
316
#define AF_EDGES_EMBEDDED 12
/* number of embedded edges */
317
318
typedef
struct
AF_AxisHintsRec_
319
{
320
FT_UInt num_segments;
/* number of used segments */
321
FT_UInt max_segments;
/* number of allocated segments */
322
AF_Segment segments;
/* segments array */
323
324
FT_UInt num_edges;
/* number of used edges */
325
FT_UInt max_edges;
/* number of allocated edges */
326
AF_Edge edges;
/* edges array */
327
328
AF_Direction major_dir;
/* either vertical or horizontal */
329
330
/* two arrays to avoid allocation penalty */
331
struct
332
{
333
AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED];
334
AF_EdgeRec edges[AF_EDGES_EMBEDDED];
335
} embedded;
336
337
338
} AF_AxisHintsRec, *AF_AxisHints;
339
340
341
#define AF_POINTS_EMBEDDED 96
/* number of embedded points */
342
#define AF_CONTOURS_EMBEDDED 8
/* number of embedded contours */
343
344
typedef
struct
AF_GlyphHintsRec_
345
{
346
FT_Memory memory;
347
348
FT_Fixed x_scale;
349
FT_Pos x_delta;
350
351
FT_Fixed y_scale;
352
FT_Pos y_delta;
353
354
FT_Int max_points;
/* number of allocated points */
355
FT_Int num_points;
/* number of used points */
356
AF_Point points;
/* points array */
357
358
FT_Int max_contours;
/* number of allocated contours */
359
FT_Int num_contours;
/* number of used contours */
360
AF_Point* contours;
/* contours array */
361
FT_Pos* contour_y_minima;
/* array with y maxima of contours */
362
FT_Pos* contour_y_maxima;
/* array with y minima of contours */
363
364
AF_AxisHintsRec axis[AF_DIMENSION_MAX];
365
366
FT_UInt32 scaler_flags;
/* copy of scaler flags */
367
FT_UInt32 other_flags;
/* free for style-specific */
368
/* implementations */
369
AF_StyleMetrics metrics;
370
371
/* Some arrays to avoid allocation penalty. */
372
/* The `embedded' structure must be the last element! */
373
struct
374
{
375
AF_Point contours[AF_CONTOURS_EMBEDDED];
376
FT_Pos contour_y_minima[AF_CONTOURS_EMBEDDED];
377
FT_Pos contour_y_maxima[AF_CONTOURS_EMBEDDED];
378
AF_PointRec points[AF_POINTS_EMBEDDED];
379
} embedded;
380
381
} AF_GlyphHintsRec;
382
383
384
#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) )
385
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
386
387
388
#ifdef FT_DEBUG_AUTOFIT
389
390
#define AF_HINTS_DO_HORIZONTAL( h ) \
391
( !af_debug_disable_horz_hints_ && \
392
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
393
394
#define AF_HINTS_DO_VERTICAL( h ) \
395
( !af_debug_disable_vert_hints_ && \
396
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
397
398
#define AF_HINTS_DO_BLUES( h ) ( !af_debug_disable_blue_hints_ )
399
400
#else
/* !FT_DEBUG_AUTOFIT */
401
402
#define AF_HINTS_DO_HORIZONTAL( h ) \
403
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
404
405
#define AF_HINTS_DO_VERTICAL( h ) \
406
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
407
408
#define AF_HINTS_DO_BLUES( h ) 1
409
410
#endif
/* !FT_DEBUG_AUTOFIT */
411
412
413
#define AF_HINTS_DO_ADVANCE( h ) \
414
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
415
416
417
FT_LOCAL( AF_Direction )
418
af_direction_compute( FT_Pos dx,
419
FT_Pos dy );
420
421
422
FT_LOCAL( FT_Error )
423
af_axis_hints_new_segment( AF_AxisHints axis,
424
FT_Memory memory,
425
AF_Segment *asegment );
426
427
FT_LOCAL( FT_Error)
428
af_axis_hints_new_edge( AF_AxisHints axis,
429
FT_Int fpos,
430
AF_Direction dir,
431
FT_Bool top_to_bottom_hinting,
432
FT_Memory memory,
433
AF_Edge *edge );
434
435
FT_LOCAL(
void
)
436
af_glyph_hints_init( AF_GlyphHints hints,
437
FT_Memory memory );
438
439
FT_LOCAL(
void
)
440
af_glyph_hints_rescale( AF_GlyphHints hints,
441
AF_StyleMetrics metrics );
442
443
FT_LOCAL( FT_Error )
444
af_glyph_hints_reload( AF_GlyphHints hints,
445
FT_Outline* outline );
446
447
FT_LOCAL(
void
)
448
af_glyph_hints_save( AF_GlyphHints hints,
449
FT_Outline* outline );
450
451
FT_LOCAL(
void
)
452
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
453
AF_Dimension dim );
454
455
FT_LOCAL(
void
)
456
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
457
AF_Dimension dim );
458
459
FT_LOCAL(
void
)
460
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
461
AF_Dimension dim );
462
463
FT_LOCAL(
void
)
464
af_glyph_hints_done( AF_GlyphHints hints );
465
466
/* */
467
468
#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord )
469
470
#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \
471
? (seg1)->pos - (seg2)->pos \
472
: (seg2)->pos - (seg1)->pos )
473
474
475
FT_END_HEADER
476
477
#endif
/* AFHINTS_H_ */
478
479
480
/* END */
aftypes.h
AF_AxisHintsRec_
Definition
afhints.h:319
AF_EdgeRec_
Definition
afhints.h:295
AF_GlyphHintsRec_
Definition
afhints.h:345
AF_PointRec_
Definition
afhints.h:248
AF_SegmentRec_
Definition
afhints.h:271
freetype
src
autofit
afhints.h
Generated by
1.18.0