diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-02 20:06:25 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | bead9f0b78380d1428f40fdab339c1c8f88fa626 (patch) | |
| tree | 960255de5a2cef661ec5d0ad3220a4b2b1738842 /vendor/stb/font.c | |
| parent | 62ef1882ab7878210f05f06504796849e412c318 (diff) | |
| download | pardes-bead9f0b78380d1428f40fdab339c1c8f88fa626.tar.gz pardes-bead9f0b78380d1428f40fdab339c1c8f88fa626.zip | |
sdl ui backend
Diffstat (limited to 'vendor/stb/font.c')
| -rw-r--r-- | vendor/stb/font.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/vendor/stb/font.c b/vendor/stb/font.c new file mode 100644 index 00000000..6c5106f6 --- /dev/null +++ b/vendor/stb/font.c @@ -0,0 +1,81 @@ +// 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 <stdlib.h> +#include <string.h> + +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; +} |
