ttf.c: glyph outline extraction, simple and composite (item 4.3.7a)
ttf_glyph_outline() decodes simple-glyph flag/coordinate runs and recursively resolves composite components into a caller-supplied point/ contour-end buffer, in Q48.16. Composite scale/rotation/skew transforms are rejected with TTF_ERR_UNSUPPORTED rather than mis-rendered, since the shared q48_mul/q48_div are unsigned-only; translation-only composites (the only kind the v1 glyph repertoire uses) apply cleanly via q48_add. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5f6cc054d4
commit
70b6918279
@@ -55,6 +55,18 @@ extern "C" {
|
||||
#define TTF_ERR_BAD_TABLE -3
|
||||
#define TTF_ERR_BAD_GLYPH_INDEX -4
|
||||
#define TTF_ERR_OUT_OF_BOUNDS -5
|
||||
#define TTF_ERR_TOO_MANY_POINTS -6
|
||||
#define TTF_ERR_TOO_MANY_CONTOURS -7
|
||||
#define TTF_ERR_TOO_DEEP -8 /* composite glyph nesting exceeded TTF_MAX_COMPOSITE_DEPTH */
|
||||
#define TTF_ERR_UNSUPPORTED -9 /* e.g. a non-identity composite transform or point-matched
|
||||
* component args — see ttf.c's file header comment; not a
|
||||
* malformed font, just a code path this parser doesn't
|
||||
* implement yet */
|
||||
|
||||
/* Recursion guard for nested composite glyphs (a component referencing a
|
||||
* component). The TTF spec doesn't hard-cap this; this is a defensive
|
||||
* limit for freestanding/kernel-stack safety. */
|
||||
#define TTF_MAX_COMPOSITE_DEPTH 8
|
||||
|
||||
/** Glyph index returned for "no mapping" by ttf_codepoint_to_glyph(). */
|
||||
#define TTF_GLYPH_MISSING 0
|
||||
@@ -125,6 +137,51 @@ uint32_t ttf_codepoint_to_glyph(const ttf_font_t *font, uint32_t codepoint);
|
||||
int ttf_glyph_header(const ttf_font_t *font, uint32_t glyph_index,
|
||||
ttf_glyph_header_t *out);
|
||||
|
||||
/** One outline point, in raw font design units (NOT scaled by unitsPerEm —
|
||||
* that's the caller's job, same convention as ttf_glyph_header_t's bbox),
|
||||
* expressed in Q48.16. Two's-complement negative values are expected and
|
||||
* correct for q48_add/q48_sub and for q48_from_u64-style left-shift
|
||||
* conversion; this module never calls q48_mul/q48_div on outline
|
||||
* coordinates (see ttf.c's file header comment for why). */
|
||||
typedef struct {
|
||||
q48_16_t x, y;
|
||||
uint8_t on_curve;
|
||||
} ttf_point_t;
|
||||
|
||||
/** Simple- and composite-glyph outline, flattened to one point list plus
|
||||
* per-contour end indices (TrueType convention: contour_ends[c] is the
|
||||
* index of the LAST point of contour c, inclusive; points are shared
|
||||
* across contours only in the sense that contour c+1 starts right after
|
||||
* contour_ends[c]). Caller supplies both backing arrays — this module
|
||||
* never allocates. */
|
||||
typedef struct {
|
||||
ttf_point_t *points;
|
||||
uint32_t max_points;
|
||||
uint32_t point_count;
|
||||
|
||||
uint16_t *contour_ends;
|
||||
uint32_t max_contours;
|
||||
uint32_t contour_count;
|
||||
} ttf_outline_t;
|
||||
|
||||
/**
|
||||
* ttf_glyph_outline - Extract a glyph's outline (simple or composite,
|
||||
* recursively resolving composite components) into caller-supplied
|
||||
* buffers.
|
||||
*
|
||||
* Composite components with a non-identity transform (any scale/rotation/
|
||||
* skew, i.e. anything but a pure (dx,dy) translation) or with
|
||||
* point-matched (rather than xy-offset) placement args return
|
||||
* TTF_ERR_UNSUPPORTED rather than silently producing a wrong outline —
|
||||
* see ttf.c's file header comment for why, and check that limitation
|
||||
* before relying on this for an arbitrary font.
|
||||
*
|
||||
* @return TTF_OK, or a TTF_ERR_* code (including TTF_ERR_TOO_MANY_POINTS/
|
||||
* _CONTOURS if a caller buffer is too small, and TTF_ERR_TOO_DEEP
|
||||
* if composite nesting exceeds TTF_MAX_COMPOSITE_DEPTH)
|
||||
*/
|
||||
int ttf_glyph_outline(const ttf_font_t *font, uint32_t glyph_index, ttf_outline_t *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user