// stb_truetype wrapper for ui_sdl.zig. See font.h. Compiled into the SDL UI // backend module alongside stb_truetype_impl.c (which defines the impl). #include "font.h" #include "stb_truetype.h" #include #include struct UIFont { stbtt_fontinfo info; const uint8_t *data; }; UIFont *ui_font_new(const uint8_t *data, int32_t len) { if (!data || len <= 0) return NULL; UIFont *f = (UIFont *)calloc(1, sizeof(UIFont)); if (!f) return NULL; f->data = data; int offset = stbtt_GetFontOffsetForIndex(data, 0); if (offset < 0 || !stbtt_InitFont(&f->info, (const unsigned char *)data, offset)) { free(f); return NULL; } return f; } void ui_font_free(UIFont *f) { free(f); } float ui_font_scale_for_height(UIFont *f, float px) { return stbtt_ScaleForPixelHeight(&f->info, px); } void ui_font_cell_metrics(UIFont *f, float scale, int32_t *cell_w, int32_t *cell_h, int32_t *ascent) { int asc = 0, desc = 0, gap = 0; stbtt_GetFontVMetrics(&f->info, &asc, &desc, &gap); int a = (int)(asc * scale + 0.5f); int d = (int)(-desc * scale + 0.5f); int g = (int)(gap * scale + 0.5f); *ascent = a; *cell_h = a + d + g; if (*cell_h < 1) *cell_h = 1; // monospace advance of 'M' int adv = 0, lsb = 0; stbtt_GetCodepointHMetrics(&f->info, 'M', &adv, &lsb); int w = (int)(adv * scale + 0.5f); if (w < 1) w = 1; *cell_w = w; } int ui_font_raster(UIFont *f, float scale, int32_t cp, uint8_t *out, int32_t stride, int32_t cell_w, int32_t cell_h, int32_t ascent) { if (!out || cell_w <= 0 || cell_h <= 0) return 0; // zero the cell for (int y = 0; y < cell_h; y++) memset(out + (size_t)y * stride, 0, (size_t)cell_w); int w = 0, h = 0, xoff = 0, yoff = 0; unsigned char *bm = stbtt_GetCodepointBitmap(&f->info, scale, scale, cp, &w, &h, &xoff, &yoff); if (!bm || w <= 0 || h <= 0) { if (bm) stbtt_FreeBitmap(bm, NULL); return 0; } // origin = (0, baseline=ascent); glyph top-left = (xoff, ascent + yoff). int gx = xoff; int gy = ascent + yoff; for (int y = 0; y < h; y++) { int dy = gy + y; if (dy < 0 || dy >= cell_h) continue; for (int x = 0; x < w; x++) { int dx = gx + x; if (dx < 0 || dx >= cell_w) continue; uint8_t v = bm[y * w + x]; if (v) out[(size_t)dy * stride + dx] = v; } } stbtt_FreeBitmap(bm, NULL); return 1; }