/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. This file is part of the StarForth project. Licensed under the StarForth License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://github.com/star.4th@proton.me/StarForth/LICENSE.txt This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. See the License for the specific language governing permissions and limitations under the License. */ /** * ttf.h - TrueType font parser core (Freestanding) * * FABRIC.md item 4.3.7. Reads a TTF's sfnt directory plus head/maxp/loca/ * glyf/cmap tables, resolving a Unicode codepoint to a glyph index and its * outline header (contour count, bounding box). Does NOT extract outline * points or rasterize — that is 4.3.7a/4.3.7c. No floating point; all * fields read here are raw integers straight from the font's own * big-endian on-disk format (see FABRIC.md §27.7 decision #2 for why the * Q48.16-vs-float call was made, and why it doesn't bind this file, which * never scales anything). * * cmap: only format 4 (Windows/Unicode BMP) subtables are resolved. This * covers ASCII and all of the BMP, which is what the v1 glyph repertoire * (§27.6.4) needs. Format 12 (supplementary planes) is deferred — no * v1 glyph requires it. */ #ifndef STARKERNEL_TTF_H #define STARKERNEL_TTF_H #include #include #include "q48_16.h" #ifdef __cplusplus extern "C" { #endif #define TTF_OK 0 #define TTF_ERR_BAD_SFNT -1 #define TTF_ERR_TABLE_MISSING -2 #define TTF_ERR_BAD_TABLE -3 #define TTF_ERR_BAD_GLYPH_INDEX -4 #define TTF_ERR_OUT_OF_BOUNDS -5 /** Glyph index returned for "no mapping" by ttf_codepoint_to_glyph(). */ #define TTF_GLYPH_MISSING 0 /** * Parsed font handle. Borrows the caller's buffer (does not copy or own * it) — the buffer must outlive the ttf_font_t. */ typedef struct { const uint8_t *data; uint32_t size; uint32_t head_off; uint32_t maxp_off; uint32_t loca_off; uint32_t loca_len; uint32_t glyf_off; uint32_t glyf_len; uint16_t units_per_em; int16_t index_to_loc_format; /* 0 = Offset16 (x2), 1 = Offset32 */ uint16_t num_glyphs; /* Selected cmap subtable (format 4 only, see file header comment). */ uint32_t cmap_subtable_off; int has_cmap; } ttf_font_t; /** Raw glyf record header, per §27.6/4.3.7's "done when" clause. */ typedef struct { int16_t num_contours; /* >= 0 simple glyph, < 0 composite glyph */ int16_t x_min; int16_t y_min; int16_t x_max; int16_t y_max; uint32_t glyf_offset; /* absolute file offset of this glyph's record */ uint32_t glyf_length; /* bytes; 0 for an empty glyph (e.g. space) */ } ttf_glyph_header_t; /** * ttf_parse - Locate and validate the sfnt directory and the head/maxp/ * loca/glyf tables (cmap is optional; ttf_codepoint_to_glyph() fails * cleanly if absent). Does not copy `data` — `out` borrows it. * * @param data Whole .ttf file contents * @param size Length of data in bytes * @param out Parsed handle to populate * @return TTF_OK, or a TTF_ERR_* code */ int ttf_parse(const uint8_t *data, uint32_t size, ttf_font_t *out); /** * ttf_codepoint_to_glyph - Resolve a Unicode codepoint via the font's * format-4 cmap subtable. * * @return glyph index, or TTF_GLYPH_MISSING if unmapped or no cmap */ uint32_t ttf_codepoint_to_glyph(const ttf_font_t *font, uint32_t codepoint); /** * ttf_glyph_header - Read a glyph's outline header (contour count, * bounding box) via loca + glyf. Does not extract contour points. * * @param glyph_index As returned by ttf_codepoint_to_glyph() * @param out Header to populate * @return TTF_OK, or a TTF_ERR_* code */ int ttf_glyph_header(const ttf_font_t *font, uint32_t glyph_index, ttf_glyph_header_t *out); #ifdef __cplusplus } #endif #endif /* STARKERNEL_TTF_H */