ttf.c: rasterization -- Bezier flattening + even-odd scanline fill
Punch list §25 item 4.3.7c complete. ttf_rasterize_glyph() flattens quadratic-Bezier contours (fixed 8-segment subdivision, matching CIRCLE/ELLIPSE's fixed-segment precedent) and fills them into a caller-supplied bitmap via even-odd scanline fill, no AA. A local signed Q48.16 multiply (q48_smul) handles negative outline coordinates, since the shared q48_mul/q48_div are unsigned-only. Verified two ways: tools/ttftest.c's ASCII-art dump + structural checks for 'A'/'.'/'a', all recognizable and passing; and a live amd64 screendump via a throwaway TTF-PROBE word (loaded the font capsule, rasterized 'A', blit via fb_put_pixel), showing a clearly legible 'A' on the CANVAS -- probe reverted immediately after capture, only the permanent ttf.c/ttf.h rasterizer remains. Compile-checked clean on all three architectures (hal/*.c wildcard); this item's own acceptance is the amd64 screendump, not a three-arch boot (that's 4.3.7f). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2ef8d26c6f
commit
095860251a
@@ -182,6 +182,42 @@ typedef struct {
|
||||
*/
|
||||
int ttf_glyph_outline(const ttf_font_t *font, uint32_t glyph_index, ttf_outline_t *out);
|
||||
|
||||
/** A caller-owned 8-bit-per-pixel bitmap. `ttf_rasterize_glyph()` writes
|
||||
* `fill_value` into covered pixels and leaves everything else untouched
|
||||
* (it does not clear the buffer first — caller's job, so repeated
|
||||
* rasterization into the same bitmap, e.g. for a text run, composites
|
||||
* correctly without an extra clear between glyphs). */
|
||||
typedef struct {
|
||||
uint8_t *pixels;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} ttf_bitmap_t;
|
||||
|
||||
/**
|
||||
* ttf_rasterize_glyph - Flatten a glyph's outline (quadratic Bezier
|
||||
* contours, fixed segment count per curve — see ttf.c's file header
|
||||
* comment) and fill it into `out` using the even-odd rule (FABRIC.md item
|
||||
* 4.3.7c; see that item's completion note for why even-odd rather than
|
||||
* nonzero winding — correct for the v1 glyph repertoire's non-self-
|
||||
* intersecting nested contours, not necessarily for an arbitrary font).
|
||||
* No antialiasing (explicitly deferred, per 4.3.7c's own "done when"
|
||||
* clause). Never allocates — flattening uses a fixed-size local buffer
|
||||
* bounded by TTF_RASTER_MAX_POINTS/TTF_RASTER_MAX_CONTOURS.
|
||||
*
|
||||
* @param scale Font-design-units-to-pixels scale, Q48.16, e.g.
|
||||
* q48_div(q48_from_u64(size_px), q48_from_u64(font->units_per_em))
|
||||
* @param origin_x Pixel-space X (Q48.16) of the glyph's (0,0) font origin
|
||||
* within `out`
|
||||
* @param origin_y Pixel-space Y (Q48.16) of the glyph's baseline (font
|
||||
* y=0) within `out`; font Y-up is flipped to raster
|
||||
* Y-down internally
|
||||
* @return TTF_OK, or a TTF_ERR_* code (including TTF_ERR_TOO_MANY_POINTS/
|
||||
* _CONTOURS if the flattened outline exceeds the local buffer)
|
||||
*/
|
||||
int ttf_rasterize_glyph(const ttf_font_t *font, uint32_t glyph_index,
|
||||
q48_16_t scale, q48_16_t origin_x, q48_16_t origin_y,
|
||||
uint8_t fill_value, ttf_bitmap_t *out);
|
||||
|
||||
#ifdef __STARKERNEL__
|
||||
#include "capsule.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user