commit 00288db
uint
·
2026-05-13 23:07:29 +0000 UTC
parent 7853789
cache schrift glyphs (up to 256)
2 files changed,
+71,
-34
+61,
-33
1@@ -1,9 +1,13 @@
2 #include <stdlib.h>
3+#include <string.h>
4
5 #include "draw.h"
6
7 static void blend(uint32_t* dst, int w, int h, int x, int y, uint8_t alpha,
8 uint32_t fg);
9+static Glyph* get_glyph(Fontface* f, uint32_t cp);
10+
11+static Glyph glyphs[GLYPH_CACHE_MAX];
12
13 /**
14 * @brief blend a pixel using alpha compositong
15@@ -42,6 +46,52 @@ static void blend(uint32_t* dst, int w, int h, int x, int y, uint8_t alpha,
16 px[3] = 255;
17 }
18
19+/** TODO
20+ */
21+static Glyph* get_glyph(Fontface* f, uint32_t cp)
22+{
23+ SFT_Glyph glyph;
24+ SFT_GMetrics gm;
25+ SFT_Image img;
26+ Glyph* g;
27+
28+ if (cp >= GLYPH_CACHE_MAX)
29+ return NULL;
30+
31+ g = &glyphs[cp];
32+ if (g->valid)
33+ return g;
34+
35+ if (sft_lookup(&f->sft, cp, &glyph) < 0)
36+ return NULL;
37+ if (sft_gmetrics(&f->sft, glyph, &gm) < 0)
38+ return NULL;
39+ if (gm.minWidth <= 0 || gm.minHeight <= 0)
40+ return NULL;
41+
42+ g->bmp = calloc(gm.minWidth * gm.minHeight, 1);
43+ if (!g->bmp)
44+ return NULL;
45+
46+ img.pixels = g->bmp;
47+ img.width = gm.minWidth;
48+ img.height = gm.minHeight;
49+
50+ if (sft_render(&f->sft, glyph, img) < 0) {
51+ free(g->bmp);
52+ memset(g, 0, sizeof(*g));
53+ return NULL;
54+ }
55+
56+ g->w = gm.minWidth;
57+ g->h = gm.minHeight;
58+ g->lsb = gm.leftSideBearing;
59+ g->yoff = gm.yOffset;
60+ g->valid = true;
61+
62+ return g;
63+}
64+
65 void draw_clear(uint32_t* dst, int w, int h, uint32_t col)
66 {
67 for (int i = 0; i < w*h; i++)
68@@ -78,49 +128,27 @@ void draw_caret(uint32_t* dst, int w, int h, int cl, int rw, int cw, int ch,
69 }
70
71 void draw_codepoint(Fontface* f, uint32_t* dst, int w, int h, int x,
72- int baseline, uint32_t cp, uint32_t fg)
73+ int baseline, uint32_t cp, uint32_t fg)
74 {
75- SFT_Glyph glyph;
76- SFT_GMetrics gm;
77- SFT_Image img;
78- uint8_t* bmp;
79- int bx;
80- int by;
81+ Glyph* g;
82
83- /* get glyph metics */
84 if (!f || !f->font || !dst)
85 return;
86- if (sft_lookup(&f->sft, cp, &glyph) < 0)
87- return;
88- if (sft_gmetrics(&f->sft, glyph, &gm) < 0)
89- return;
90- if (gm.minWidth <= 0 || gm.minHeight <= 0)
91- return;
92
93- bmp = calloc(gm.minWidth*gm.minHeight, 1);
94- if (!bmp)
95+ g = get_glyph(f, cp);
96+ if (!g)
97 return;
98
99- img.pixels = bmp;
100- img.width = gm.minWidth;
101- img.height = gm.minHeight;
102-
103- if (sft_render(&f->sft, glyph, img) == 0) {
104- /* copy bmp to dst */
105- for (by = 0; by < gm.minHeight; by++) {
106- for (bx = 0; bx < gm.minWidth; bx++) {
107- /* TODO: proper aa controls */
108- uint8_t a = bmp[(by*gm.minWidth) + bx]; /* alpha */
109- uint8_t aa = f->aa ? a : (a > 128 ? 255 : 0);
110+ for (int by = 0; by < g->h; by++) {
111+ for (int bx = 0; bx < g->w; bx++) {
112+ uint8_t a = g->bmp[(by * g->w) + bx];
113+ uint8_t aa = f->aa ? a : (a > 128 ? 255 : 0);
114
115- /* translate bpm pixels to dst pixels */
116- int dst_x = x + (int)gm.leftSideBearing + bx;
117- int dst_y = baseline + gm.yOffset + by;
118+ int dst_x = x + g->lsb + bx;
119+ int dst_y = baseline + g->yoff + by;
120
121- blend(dst, w, h, dst_x, dst_y, aa, fg);
122- }
123+ blend(dst, w, h, dst_x, dst_y, aa, fg);
124 }
125 }
126- free(bmp);
127 }
128
+10,
-1
1@@ -5,7 +5,16 @@
2
3 #include "font.h"
4
5-/* TODO: proper structs and faster drawing with damage for drawing shaepes*/
6+#define GLYPH_CACHE_MAX 256
7+
8+typedef struct {
9+ bool valid;
10+ int w;
11+ int h;
12+ int lsb;
13+ int yoff;
14+ uint8_t* bmp;
15+} Glyph;
16
17 /**
18 * @brief clear a buffer size wxh