#pragma once #include #include #include "ttf_math.h" typedef struct ttf_face ttf_face_t; typedef struct ttf_face { const SUINT8* data; UINTN size; // head SUINT32 units_per_em; SSINT16 index_to_loc_format; // 0 = short, 1 = long // hhea SSINT16 hhea_ascender; SSINT16 hhea_descender; SSINT16 hhea_line_gap; SUINT16 num_long_hor_metrics; // maxp SUINT16 num_glyphs; SUINT16 max_points; SUINT16 max_contours; // os/2 SSINT16 os2_ascender; SSINT16 os2_descender; SSINT16 os2_line_gap; // Table directory (sorted by tag at open time) struct { char tag[4]; SUINT32 offset; SUINT32 length; } tables[32]; SUINT16 num_tables; // Cached pointers into data[] const SUINT8* loca; // size depends on num_glyphs and format const SUINT8* glyf; SUINT32 glyf_len; const SUINT8* hmtx; SUINT32 hmtx_len; const SUINT8* cmap; } ttf_face_t; // Decomposed glyph: contours in pixel space (26.6 fp) ready to scan. typedef struct ttf_outline { f26_6 x[1024]; f26_6 y[1024]; SUINT8 on_curve[1024]; SUINT16 first[64]; SUINT16 last[64]; SUINT16 num_contours; SUINT16 num_points; // Bounding box in pixel space (26.6 fp). SSINT32 xmin, ymin, xmax, ymax; // Pen advance in pixel space (26.6 fp). f26_6 advance; } ttf_outline_t; typedef struct ttf_seg { f26_6 x0, y0, x1, y1; // line / quad end points f26_6 cx, cy; // quadratic control (set to x0/y0 if is_line) SUINT8 is_line; // 1 = line, 0 = quad } ttf_seg_t; // Parse the glyf entry for glyph_id. Fills outline already // scaled to pixel_size_px. Returns false on composite / parse error. bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, SUINT32 pixel_size_px, ttf_outline_t* out); // UTF-8 decoder. *p advances past the codepoint. Returns -1 on error. SSINT32 ttf_utf8_decode(const char** p); // cmap lookup — returns glyph_id (0 = notdef). SUINT16 ttf_cmap_lookup(ttf_face_t* face, SSINT32 cp); // Decompose outline into a flat array of line/quadratic segments. // out must have room for 2*num_points + num_contours entries. void ttf_outline_to_segments(const ttf_outline_t* outline, ttf_seg_t* segs, SUINT32* num_segs); // Scanline rasterize segments into per-pixel coverage. // coverage[w*h] gets values in [0, N] where N = supersample count. void ttf_rasterize(const ttf_seg_t* segs, SUINT32 num_segs, SSINT32 x0, SSINT32 y0, SUINT32 w, SUINT32 h, SUINT8* coverage, SUINT32 N);