From 874252db87cb83de3c223260b67a1224238eee54 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 16 Jul 2025 05:03:40 -0500 Subject: [PATCH] fix text menu render --- prosperon/clay.cm | 18 ++++++++++-------- prosperon/draw2d.cm | 3 +-- prosperon/prosperon.cm | 5 ++--- scripts/graphics.cm | 13 +++++-------- source/font.c | 36 ++++++++++++++++-------------------- source/font.h | 4 ++-- source/jsffi.c | 29 +++++++++++++---------------- 7 files changed, 49 insertions(+), 59 deletions(-) diff --git a/prosperon/clay.cm b/prosperon/clay.cm index c0224d49..d3a721ce 100644 --- a/prosperon/clay.cm +++ b/prosperon/clay.cm @@ -32,7 +32,7 @@ var clay_base = { slice: 0, font: 'smalle.16', font_size: null, - color: [1,1,1,1], + color: {r:1,g:1,b:1,a:1}, spacing:0, padding:0, margin:0, @@ -212,10 +212,12 @@ clay.image = function image(path, ...configs) clay.text = function text(str, ...configs) { var config = rectify_configs(configs); - config.size ??= {width:0, height:0}; -// config.font = graphics.get_font(config.font) - var tsize = {width: 12*str.length, height: 8}; //config.font.text_size(str, 0, 0, config.size.width); - config.size = {width: Math.max(config.size.width, tsize.width), height: Math.max(config.size.height, tsize.height)}; + config.size ??= [0,0]; + config.font = graphics.get_font(config.font) + var tsize = graphics.font_text_size(config.font, str, 0, config.size.x); + tsize.x = Math.ceil(tsize.x) + tsize.y = Math.ceil(tsize.y) + config.size = config.size.map((x,i) => Math.max(x, tsize[i])); config.text = str; add_item(config); } @@ -235,8 +237,8 @@ var button_base = Object.assign(Object.create(clay_base), { clay.button = function button(str, action, config = {}) { config.__proto__ = button_base; -// config.font = graphics.get_font(config.font) - config.size = 12;//config.font.text_size(str) + config.font = graphics.get_font(config.font) + config.size = graphics.font_text_size(config.font, str, 0, 0) add_item(config); config.text = str; config.action = action; @@ -269,7 +271,7 @@ clay.draw_commands = function draw_commands(cmds, pos = {x:0, y:0}, mousepos = { draw.rectangle(boundingbox, config.background_color); if (config.text) - draw.text(config.text, content, config.font, config.font_size, config.color, config.size.width); + draw.text(config.text, content, config.font, config.color, config.size.width); if (config.image) draw.image(config.image, content, 0, config.color); } diff --git a/prosperon/draw2d.cm b/prosperon/draw2d.cm index 308cd70d..131e504e 100644 --- a/prosperon/draw2d.cm +++ b/prosperon/draw2d.cm @@ -158,12 +158,11 @@ draw.circle = function render_circle(pos, radius, defl, material) { draw.ellipse(pos, [radius,radius], defl, material) } -draw.text = function text(text, pos, font = 'fonts/c64.ttf', size = 8, color = {r:1,g:1,b:1,a:1}, wrap = 0) { +draw.text = function text(text, pos, font = 'fonts/c64.8', color = {r:1,g:1,b:1,a:1}, wrap = 0) { add_command("draw_text", { text, pos, font, - size, wrap, material: {color} }) diff --git a/prosperon/prosperon.cm b/prosperon/prosperon.cm index 0d3f0ba6..9287a528 100644 --- a/prosperon/prosperon.cm +++ b/prosperon/prosperon.cm @@ -214,14 +214,13 @@ function translate_draw_commands(commands) { if (!cmd.pos) break // Get font from the font string (e.g., "smalle.16") - var font = graphics.get_font(cmd.font, cmd.size) + var font = graphics.get_font(cmd.font) if (!font || !font.texture || !font.texture.id) break // Create text geometry buffer var text_mesh = graphics.make_text_buffer( cmd.text, - {x: cmd.pos.x, y: cmd.pos.y, width: 200, height: 50}, - cmd.size, + {x: cmd.pos.x, y: cmd.pos.y}, [cmd.material.color.r, cmd.material.color.g, cmd.material.color.b, cmd.material.color.a], cmd.wrap || 0, font diff --git a/scripts/graphics.cm b/scripts/graphics.cm index a7c0a8e4..7381ba20 100644 --- a/scripts/graphics.cm +++ b/scripts/graphics.cm @@ -400,8 +400,10 @@ Stores previously loaded fonts. Keyed by e.g. "path.ttf.16" -> fontObject. var fontcache = {} var datas = [] -graphics.get_font = function get_font(path, size) { +graphics.get_font = function get_font(path) { + if (typeof path != 'string') return path var parts = path.split('.') + var size = 16 // default size if (!isNaN(parts[1])) { path = parts[0] size = Number(parts[1]) @@ -413,12 +415,7 @@ graphics.get_font = function get_font(path, size) { if (fontcache[fontstr]) return fontcache[fontstr] var data = io.slurpbytes(fullpath) - // Ensure size is a proper number - var numericSize = Number(size) - if (isNaN(numericSize) || numericSize <= 0) { - numericSize = 16 // default size - } - var font = graphics.make_font(data, numericSize) + var font = graphics.make_font(data, size) // Load font texture via renderer actor (async) if (renderer_actor) { @@ -436,7 +433,7 @@ graphics.get_font = function get_font(path, size) { } fontcache[fontstr] = font - + return font } diff --git a/source/font.c b/source/font.c index ea690394..dec25feb 100644 --- a/source/font.c +++ b/source/font.c @@ -103,13 +103,13 @@ void sdrawCharacter(struct text_vert **buffer, stbtt_packedchar c, HMM_Vec2 curs arrput(*buffer, vert); } -void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cursor, float scale, colorf color) +void draw_char_verts(struct text_vert **buffer, struct character c, HMM_Vec2 cursor, colorf color) { // packedchar has // Adds four verts: bottom left, bottom right, top left, top right text_vert bl; - bl.pos.x = cursor.X + c.quad.x * scale; - bl.pos.y = cursor.Y + c.quad.y * scale; + bl.pos.x = cursor.X + c.quad.x; + bl.pos.y = cursor.Y + c.quad.y; bl.uv.x = c.uv.x; bl.uv.y = c.uv.y; bl.color = color; @@ -117,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 * scale; + br.pos.x += c.quad.w; br.uv.x += c.uv.w; arrput(*buffer, br); text_vert ul = bl; - ul.pos.y += c.quad.h * scale; + ul.pos.y += c.quad.h; ul.uv.y += c.uv.h; arrput(*buffer, ul); @@ -159,16 +159,14 @@ const char *esc_color(const char *c, struct rgba *color, struct rgba defc) return c; } -// text is a string, font f, size is height in pixels, wrap is how long a line is before wrapping. -1to not wrap -HMM_Vec2 measure_text(const char *text, font *f, float size, float letterSpacing, float wrap) +// text is a string, font f, wrap is how long a line is before wrapping. -1to not wrap +HMM_Vec2 measure_text(const char *text, font *f, float letterSpacing, float wrap) { int breakAtWord = 0; HMM_Vec2 dim = {0}; float maxWidth = 0; // Maximum width of any line float lineWidth = 0; // Current line width - float scale = size / f->height; - float lineHeight = (f->ascent - f->descent) * scale; - letterSpacing *= scale; + float lineHeight = f->ascent - f->descent; float height = lineHeight; // Total height const char *wordStart = text; // Start of the current word for word wrapping @@ -233,36 +231,34 @@ HMM_Vec2 measure_text(const char *text, font *f, float size, float letterSpacing return dim; } /* pos given in screen coordinates */ -struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, float scale, colorf color, float wrap) { +struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, colorf color, float wrap) { text_vert *buffer = NULL; HMM_Vec2 cursor = pos; - float lineHeight = (f->ascent - f->descent) * scale; + float lineHeight = f->ascent - f->descent; 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 + scaledLinegap; + cursor.y -= lineHeight + f->linegap; lineWidth = 0; continue; } struct character chara = f->Characters[(unsigned char)*c]; - float scaledAdvance = chara.advance * scale; - if (wrap > 0 && lineWidth + scaledAdvance > wrap) { + if (wrap > 0 && lineWidth + chara.advance > wrap) { cursor.x = pos.x; - cursor.y -= lineHeight + scaledLinegap; + cursor.y -= lineHeight + f->linegap; lineWidth = 0; } if (!isspace(*c)) - draw_char_verts(&buffer, chara, cursor, scale, color); + draw_char_verts(&buffer, chara, cursor, color); - lineWidth += scaledAdvance; - cursor.x += scaledAdvance; + lineWidth += chara.advance; + cursor.x += chara.advance; } return buffer; diff --git a/source/font.h b/source/font.h index 1bfb20df..9055f671 100644 --- a/source/font.h +++ b/source/font.h @@ -57,7 +57,7 @@ typedef struct Character glyph; void font_free(JSRuntime *rt,font *f); struct sFont *MakeFont(void *data, size_t len, int height); -struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, float scale, colorf color, float wrap); -HMM_Vec2 measure_text(const char *text, font *f, float scale, float letterSpacing, float wrap); +struct text_vert *renderText(const char *text, HMM_Vec2 pos, font *f, colorf color, float wrap); +HMM_Vec2 measure_text(const char *text, font *f, float letterSpacing, float wrap); #endif diff --git a/source/jsffi.c b/source/jsffi.c index f121e972..eef729cc 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -742,14 +742,11 @@ int point2segindex(HMM_Vec2 p, HMM_Vec2 *segs, double slop) { JSC_CCALL(os_make_text_buffer, const char *s = JS_ToCString(js, argv[0]); rect rectpos = js2rect(js,argv[1]); - float size = js2number(js,argv[2]); - font *f = js2font(js,argv[5]); - if (!size) size = f->height; - colorf c = js2color(js,argv[3]); - int wrap = js2number(js,argv[4]); + font *f = js2font(js,argv[4]); + colorf c = js2color(js,argv[2]); + int wrap = js2number(js,argv[3]); HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y }; - float scale = size / f->height; - text_vert *buffer = renderText(s, startpos, f, scale, c, wrap); + text_vert *buffer = renderText(s, startpos, f, c, wrap); ret = quads_to_mesh(js,buffer); JS_FreeCString(js, s); arrfree(buffer); @@ -1046,13 +1043,13 @@ JSC_GET(font, height, number) JSC_GET(font, ascent, number) JSC_GET(font, descent, number) -JSC_SCALL(font_text_size, - font *f = js2font(js,self); - float size = js2number(js,argv[0]); - if (!size) size = f->height; - float letterSpacing = js2number(js,argv[1]); - float wrap = js2number(js,argv[2]); - ret = vec22js(js,measure_text(str, f, size, letterSpacing, wrap)); +JSC_CCALL(graphics_font_text_size, + font *f = js2font(js,argv[0]); + const char *str = JS_ToCString(js, argv[1]); + float letterSpacing = js2number(js,argv[2]); + float wrap = js2number(js,argv[3]); + ret = vec22js(js,measure_text(str, f, letterSpacing, wrap)); + JS_FreeCString(js, str); ) static const JSCFunctionListEntry js_font_funcs[] = { @@ -1060,7 +1057,6 @@ static const JSCFunctionListEntry js_font_funcs[] = { MIST_GET(font, height), MIST_GET(font, ascent), MIST_GET(font, descent), - MIST_FUNC_DEF(font, text_size, 3), }; // input: (encoded image data of jpg, png, bmp, tiff) @@ -1526,7 +1522,7 @@ JSC_CCALL(graphics_save_jpg, ) static const JSCFunctionListEntry js_graphics_funcs[] = { - MIST_FUNC_DEF(os, make_text_buffer, 6), + MIST_FUNC_DEF(os, make_text_buffer, 5), MIST_FUNC_DEF(os, rectpack, 3), MIST_FUNC_DEF(os, make_texture, 1), MIST_FUNC_DEF(os, make_gif, 1), @@ -1537,6 +1533,7 @@ static const JSCFunctionListEntry js_graphics_funcs[] = { MIST_FUNC_DEF(graphics, hsl_to_rgb, 3), MIST_FUNC_DEF(graphics, save_png, 4), MIST_FUNC_DEF(graphics, save_jpg, 4), + MIST_FUNC_DEF(graphics, font_text_size, 4), }; static const JSCFunctionListEntry js_video_funcs[] = {