summaryrefslogtreecommitdiff
path: root/vendor/stb/font.c
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-02 20:06:25 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commitbead9f0b78380d1428f40fdab339c1c8f88fa626 (patch)
tree960255de5a2cef661ec5d0ad3220a4b2b1738842 /vendor/stb/font.c
parent62ef1882ab7878210f05f06504796849e412c318 (diff)
downloadpardes-bead9f0b78380d1428f40fdab339c1c8f88fa626.tar.gz
pardes-bead9f0b78380d1428f40fdab339c1c8f88fa626.zip
sdl ui backend
Diffstat (limited to 'vendor/stb/font.c')
-rw-r--r--vendor/stb/font.c81
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;
+}