fix text menu render

This commit is contained in:
2025-07-16 05:03:40 -05:00
parent 13dd685f65
commit 874252db87
7 changed files with 49 additions and 59 deletions

View File

@@ -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);
}

View File

@@ -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}
})

View File

@@ -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

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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[] = {