ttf.c: glyph raster cache, fixed slots, no allocation (item 4.3.7d)
Punch list §25 item 4.3.7d complete. ttf_raster_cache_get() looks up (font, codepoint, size_px) in a caller-owned fixed slot array, evicting round-robin once full, rasterizing into a slot on a miss. Verified live in tools/ttftest.c: an identical (font, 'A', 24px) call made twice returns was_hit=0 then was_hit=1, and the slot's own hits counter reads exactly 1 afterward -- checked programmatically. A different-codepoint call misses again, proving the key actually discriminates. Wall-clock timing (miss 0.040ms vs hit 0.001ms) is printed as informational corroboration only, not the load-bearing check. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
095860251a
commit
2db4603d04
@@ -218,6 +218,57 @@ 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);
|
||||
|
||||
/* Glyph raster cache (FABRIC.md item 4.3.7d). Fixed-size, caller-owned
|
||||
* slot array -- no allocation, same convention as the rest of this
|
||||
* module. Every cached bitmap is a fixed TTF_CACHE_BITMAP_DIM square,
|
||||
* rasterized with the fixed origin (TTF_CACHE_MARGIN,
|
||||
* size_px + TTF_CACHE_MARGIN) -- i.e. glyph (0,0)/baseline sits at that
|
||||
* pixel within the bitmap on every cache entry, not just fitted to each
|
||||
* glyph's own bounding box. Callers positioning text (4.3.7e) need to
|
||||
* know this fixed convention. */
|
||||
#define TTF_CACHE_MAX_SIZE_PX 64
|
||||
#define TTF_CACHE_MARGIN 8
|
||||
#define TTF_CACHE_BITMAP_DIM (TTF_CACHE_MAX_SIZE_PX + TTF_CACHE_MARGIN * 2)
|
||||
#define TTF_CACHE_BITMAP_BYTES (TTF_CACHE_BITMAP_DIM * TTF_CACHE_BITMAP_DIM)
|
||||
|
||||
typedef struct {
|
||||
int valid;
|
||||
const ttf_font_t *font;
|
||||
uint32_t codepoint;
|
||||
uint32_t size_px;
|
||||
uint32_t width, height;
|
||||
uint32_t hits; /* incremented on every cache hit; 4.3.7d's own
|
||||
* "measurable" verification reads this. */
|
||||
uint8_t pixels[TTF_CACHE_BITMAP_BYTES];
|
||||
} ttf_raster_cache_slot_t;
|
||||
|
||||
typedef struct {
|
||||
ttf_raster_cache_slot_t *slots;
|
||||
uint32_t slot_count;
|
||||
uint32_t evict_next; /* round-robin index used once every slot is full */
|
||||
} ttf_raster_cache_t;
|
||||
|
||||
/** ttf_raster_cache_init - Bind a caller-supplied slot array to `cache`
|
||||
* and mark every slot empty. */
|
||||
void ttf_raster_cache_init(ttf_raster_cache_t *cache, ttf_raster_cache_slot_t *slots,
|
||||
uint32_t slot_count);
|
||||
|
||||
/**
|
||||
* ttf_raster_cache_get - Look up (font, codepoint, size_px); on a miss,
|
||||
* rasterize and insert (evicting round-robin if every slot is full).
|
||||
* `out` borrows the winning slot's buffer directly -- valid until that
|
||||
* slot is evicted by a later call.
|
||||
*
|
||||
* @param was_hit If non-NULL, set to 1 on a cache hit, 0 if this call
|
||||
* rasterized and inserted
|
||||
* @return TTF_OK, TTF_ERR_UNSUPPORTED if size_px > TTF_CACHE_MAX_SIZE_PX,
|
||||
* or a ttf_rasterize_glyph() TTF_ERR_* code on a miss that failed
|
||||
* to rasterize
|
||||
*/
|
||||
int ttf_raster_cache_get(ttf_raster_cache_t *cache, const ttf_font_t *font,
|
||||
uint32_t codepoint, uint32_t size_px,
|
||||
ttf_bitmap_t *out, int *was_hit);
|
||||
|
||||
#ifdef __STARKERNEL__
|
||||
#include "capsule.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user