text drawing

This commit is contained in:
2025-07-15 16:22:11 -05:00
parent 09b78781e6
commit 4b817b8d1b
7 changed files with 293 additions and 41 deletions

View File

@@ -78,7 +78,6 @@ struct sFont *MakeFont(void *ttf_buffer, size_t len, int height) {
quad.h = glyph.yoff2-glyph.yoff;
newfont->Characters[c].quad = quad;
newfont->Characters[c].advance = glyph.xadvance;
// printf("glyph for %c is x0,y0,x1,y1: %d,%d,%d,%d\n xoff %g, yoff %g, xadvance %g, xoff2 %g, yoff2 %g\n", c, glyph.x0, glyph.y1, glyph.x1, glyph.y1, glyph.xoff, glyph.yoff, glyph.xadvance, glyph.xoff2, glyph.yoff2);
}
free(bitmap);
@@ -109,8 +108,8 @@ void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cur
// packedchar has
// Adds four verts: bottom left, bottom right, top left, top right
text_vert bl;
bl.pos.x = cursor.X + c.quad.x;
bl.pos.y = cursor.Y + c.quad.y;
bl.pos.x = cursor.X + c.quad.x * scale;
bl.pos.y = cursor.Y + c.quad.y * scale;
bl.uv.x = c.uv.x;
bl.uv.y = c.uv.y;
bl.color = color;
@@ -118,12 +117,12 @@ void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cur
text_vert br = bl;
br.pos.x += c.quad.w;
br.pos.x += c.quad.w * scale;
br.uv.x += c.uv.w;
arrput(*buffer, br);
text_vert ul = bl;
ul.pos.y += c.quad.h;
ul.pos.y += c.quad.h * scale;
ul.uv.y += c.uv.h;
arrput(*buffer, ul);
@@ -238,30 +237,32 @@ struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, float scal
text_vert *buffer = NULL;
HMM_Vec2 cursor = pos;
float lineHeight = f->ascent - f->descent;
float lineHeight = (f->ascent - f->descent) * scale;
float lineWidth = 0;
float scaledLinegap = f->linegap * scale;
for (const char *c = text; *c != 0; c++) {
if (*c == '\n') {
cursor.x = pos.x;
cursor.y -= lineHeight + f->linegap;
cursor.y -= lineHeight + scaledLinegap;
lineWidth = 0;
continue;
}
struct character chara = f->Characters[(unsigned char)*c];
float scaledAdvance = chara.advance * scale;
if (wrap > 0 && lineWidth + chara.advance > wrap) {
if (wrap > 0 && lineWidth + scaledAdvance > wrap) {
cursor.x = pos.x;
cursor.y -= lineHeight + f->linegap;
cursor.y -= lineHeight + scaledLinegap;
lineWidth = 0;
}
if (!isspace(*c))
draw_char_verts(&buffer, chara, cursor, scale, color);
lineWidth += chara.advance;
cursor.x += chara.advance;
lineWidth += scaledAdvance;
cursor.x += scaledAdvance;
}
return buffer;

View File

@@ -296,31 +296,61 @@ JSValue quads_to_mesh(JSContext *js, text_vert *buffer)
{
size_t verts = arrlen(buffer);
HMM_Vec2 *pos = malloc(arrlen(buffer)*sizeof(HMM_Vec2));
HMM_Vec2 *uv = malloc(arrlen(buffer)*sizeof(HMM_Vec2));
HMM_Vec4 *color = malloc(arrlen(buffer)*sizeof(HMM_Vec4));
// Allocate flat arrays for xy, uv, and color data
size_t xy_size = verts * 2 * sizeof(float);
size_t uv_size = verts * 2 * sizeof(float);
size_t color_size = verts * sizeof(SDL_FColor);
float *xy_data = malloc(xy_size);
float *uv_data = malloc(uv_size);
SDL_FColor *color_data = malloc(color_size);
for (int i = 0; i < arrlen(buffer); i++) {
pos[i] = buffer[i].pos;
uv[i] = buffer[i].uv;
color[i] = buffer[i].color;
// Convert vertex data to flat arrays
for (int i = 0; i < verts; i++) {
xy_data[i*2] = buffer[i].pos.x;
xy_data[i*2+1] = buffer[i].pos.y;
uv_data[i*2] = buffer[i].uv.x;
uv_data[i*2+1] = buffer[i].uv.y;
color_data[i].r = buffer[i].color.x;
color_data[i].g = buffer[i].color.y;
color_data[i].b = buffer[i].color.z;
color_data[i].a = buffer[i].color.w;
}
JSValue jspos = make_gpu_buffer(js, pos, sizeof(HMM_Vec2)*arrlen(buffer), 0, 2,0,0);
JSValue jsuv = make_gpu_buffer(js, uv, sizeof(HMM_Vec2)*arrlen(buffer), 0, 2,0,0);
JSValue jscolor = make_gpu_buffer(js, color, sizeof(HMM_Vec4)*arrlen(buffer), 0, 4,0,0);
size_t quads = verts/4;
size_t count = verts/2*3;
JSValue jsidx = make_quad_indices_buffer(js, quads);
size_t count = quads*6;
// Create indices
uint16_t *indices = malloc(sizeof(uint16_t)*count);
for (int i = 0, v = 0; i < count; i += 6, v += 4) {
indices[i] = v;
indices[i+1] = v+2;
indices[i+2] = v+1;
indices[i+3] = v+2;
indices[i+4] = v+3;
indices[i+5] = v+1;
}
JSValue ret = JS_NewObject(js);
JS_SetPropertyStr(js, ret, "pos", jspos);
JS_SetPropertyStr(js, ret, "uv", jsuv);
JS_SetPropertyStr(js, ret, "color", jscolor);
JS_SetPropertyStr(js, ret, "indices", jsidx);
JS_SetPropertyStr(js, ret, "vertices", number2js(js, verts));
JS_SetPropertyStr(js,ret,"num_indices", number2js(js,count));
// Create blobs for geometry data
JS_SetPropertyStr(js, ret, "xy", js_new_blob_stoned_copy(js, xy_data, xy_size));
JS_SetPropertyStr(js, ret, "xy_stride", JS_NewInt32(js, 2 * sizeof(float)));
JS_SetPropertyStr(js, ret, "uv", js_new_blob_stoned_copy(js, uv_data, uv_size));
JS_SetPropertyStr(js, ret, "uv_stride", JS_NewInt32(js, 2 * sizeof(float)));
JS_SetPropertyStr(js, ret, "color", js_new_blob_stoned_copy(js, color_data, color_size));
JS_SetPropertyStr(js, ret, "color_stride", JS_NewInt32(js, sizeof(SDL_FColor)));
JS_SetPropertyStr(js, ret, "indices", js_new_blob_stoned_copy(js, indices, sizeof(uint16_t)*count));
JS_SetPropertyStr(js, ret, "num_vertices", JS_NewInt32(js, verts));
JS_SetPropertyStr(js, ret, "num_indices", JS_NewInt32(js, count));
JS_SetPropertyStr(js, ret, "size_indices", JS_NewInt32(js, 2)); // uint16_t size
free(xy_data);
free(uv_data);
free(color_data);
free(indices);
return ret;
}
@@ -718,7 +748,8 @@ JSC_CCALL(os_make_text_buffer,
colorf c = js2color(js,argv[3]);
int wrap = js2number(js,argv[4]);
HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y };
text_vert *buffer = renderText(s, startpos, f, size, c, wrap);
float scale = size / f->height;
text_vert *buffer = renderText(s, startpos, f, scale, c, wrap);
ret = quads_to_mesh(js,buffer);
JS_FreeCString(js, s);
arrfree(buffer);