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