This commit is contained in:
John Alanbrook 2024-10-14 20:07:32 -05:00
parent 7f6996d93f
commit 2a1a5231aa
7 changed files with 132 additions and 224 deletions

View file

@ -873,6 +873,11 @@ render.rectangle = function render_rectangle(lowerleft, upperright, color, shade
check_flush(flush_poly); check_flush(flush_poly);
}; };
render.brect = function(brect, color = Color.white)
{
render.rectangle([brect.x,brect.y], [brect.x+brect.width, brect.y+brect.height], color);
}
render.rect = function(rect, color, shader, pipe) render.rect = function(rect, color, shader, pipe)
{ {
render.rectangle([rect.x-rect.w/2, rect.y-rect.h/2], [rect.x+rect.w/2, rect.y+rect.h/2], color, shader, pipe); render.rectangle([rect.x-rect.w/2, rect.y-rect.h/2], [rect.x+rect.w/2, rect.y+rect.h/2], color, shader, pipe);
@ -890,32 +895,11 @@ render.window = function render_window(pos, wh, color) {
render.box(pos.add(wh.scale(0.5)), wh, color); render.box(pos.add(wh.scale(0.5)), wh, color);
}; };
render.text_bb = function (str, size = 1, wrap = -1, pos = [0, 0]) { render.text = function (str, pos, font = cur_font, size = 1, color = Color.white, wrap = -1) {
var bb = render.text_size(str, size, wrap); if (!font) return;
var w = bb.r - bb.l; gui.text(str, pos, size, color, wrap, font); // this puts text into buffer
var h = bb.t - bb.b; cur_font = font;
bb.r += pos.x;
bb.l += pos.x;
bb.t += pos.y;
bb.b += pos.y;
return bb;
};
render.text = function (str, pos, size = 1, color = Color.white, wrap = -1, anchor = [0, 1], cursor = -1) {
var bb = render.text_bb(str, size, wrap, pos);
gui.text(str, pos, size, color, wrap, cursor); // this puts text into buffer
check_flush(render.flush_text); check_flush(render.flush_text);
return bb;
p.x -= w * anchor.x;
bb.r += w * anchor.x;
bb.l += w * anchor.x;
p.y += h * (1 - anchor.y);
bb.t += h * (1 - anchor.y);
bb.b += h * (1 - anchor.y);
return bb;
}; };
var lasttex = undefined; var lasttex = undefined;
@ -1063,7 +1047,10 @@ render.image = function image(image, pos, scale, rotation = 0, color = Color.whi
}; };
// pos is the lower left corner, scale is the width and height // pos is the lower left corner, scale is the width and height
render.slice9 = function (tex, pos, bb, scale = [tex.width, tex.height], color = Color.white) { render.slice9 = function (image, pos, bb, scale = [tex.width, tex.height], color = Color.white) {
if (typeof image === 'string')
image = game.texture(image);
var tex = image.texture;
var t = os.make_transform(); var t = os.make_transform();
t.pos = pos; t.pos = pos;
t.scale = [scale.x / tex.width, scale.y / tex.height, 1]; t.scale = [scale.x / tex.width, scale.y / tex.height, 1];
@ -1090,6 +1077,7 @@ function endframe() {
var textssbos = []; var textssbos = [];
var tdraw = 0; var tdraw = 0;
var cur_font = undefined;
render.flush_text = function () { render.flush_text = function () {
if (!render.textshader) return; if (!render.textshader) return;
@ -1105,22 +1093,18 @@ render.flush_text = function () {
} }
render.use_shader(render.textshader); render.use_shader(render.textshader);
render.use_mat({ text: render.font.texture }); render.use_mat({ text: cur_font.texture });
render.draw(shape.quad, textssbo, amt); render.draw(shape.quad, textssbo, amt);
}; };
var fontcache = {}; var fontcache = {};
render.set_font = function (path, size) {
render.get_font = function(path,size)
{
var fontstr = `${path}-${size}`; var fontstr = `${path}-${size}`;
if (render.font && fontcache[fontstr] === render.font) return; if (!fontcache[fontstr]) fontcache[fontstr] = os.make_font(path,size);
if (!fontcache[fontstr]) fontcache[fontstr] = os.make_font(path, size); return fontcache[fontstr];
}
render.flush_text();
gui.font_set(fontcache[fontstr]);
render.font = fontcache[fontstr];
};
render.doc = "Draw shapes in screen space."; render.doc = "Draw shapes in screen space.";
render.cross.doc = "Draw a cross centered at pos, with arm length size."; render.cross.doc = "Draw a cross centered at pos, with arm length size.";

View file

@ -269,7 +269,6 @@ Cmdline.register_order(
if (project.title) window.title = project.title; if (project.title) window.title = project.title;
game.engine_start(function () { game.engine_start(function () {
render.set_font("fonts/c64.ttf", 8);
if (io.exists("game.js")) global.app = actor.spawn("game.js"); if (io.exists("game.js")) global.app = actor.spawn("game.js");
else global.app = actor.spawn("scripts/nogame.js"); else global.app = actor.spawn("scripts/nogame.js");

View file

@ -6,7 +6,7 @@ struct letter {
vec2 pos; vec2 pos;
vec2 wh; vec2 wh;
vec2 uv; vec2 uv;
vec2 st; vec2 uv_size;
vec4 color; vec4 color;
}; };
@ -14,8 +14,8 @@ readonly buffer ssbo {
letter ls[]; letter ls[];
}; };
out vec2 uv; out vec2 uv; // Normalized UV, from 0 to 1 on the letter, for special effects
out vec2 fuv; out vec2 fuv; // This is the UV given to get the correct letter from the texture
out vec4 color0; out vec4 color0;
vec2 pos; vec2 pos;
@ -26,11 +26,11 @@ uniform mat4 vp;
void main() void main()
{ {
letter l = ls[gl_InstanceIndex]; letter charData = ls[gl_InstanceIndex];
fuv = l.uv + vec2(a_pos.x*l.st.x, l.st.y - a_pos.y*l.st.y); fuv = charData.uv + vec2(a_pos.x*charData.uv_size.x, charData.uv_size.y - a_pos.y*charData.uv_size.y);
uv = a_uv; uv = a_uv;
color0 = l.color; color0 = charData.color;
pos = l.pos+(a_pos*l.wh); pos = charData.pos+(a_pos*charData.wh);
vert(); vert();
gl_Position = vp * vec4(pos, 0.0, 1.0); gl_Position = vp * vec4(pos, 0.0, 1.0);
} }

View file

@ -261,6 +261,7 @@ typedef struct
uint16_t lineHeight; uint16_t lineHeight;
Clay_TextElementConfigWrapMode wrapMode; Clay_TextElementConfigWrapMode wrapMode;
struct sFont *font; struct sFont *font;
JSValue jsstr;
#ifdef CLAY_EXTEND_CONFIG_ELEMENT #ifdef CLAY_EXTEND_CONFIG_ELEMENT
CLAY_EXTEND_CONFIG_ELEMENT CLAY_EXTEND_CONFIG_ELEMENT
#endif #endif

View file

@ -36,11 +36,6 @@ void font_free(font *f)
free(f); free(f);
} }
void font_set(font *f)
{
use_font = f;
}
struct sFont *MakeSDFFont(const char *fontfile, int height) struct sFont *MakeSDFFont(const char *fontfile, int height)
{ {
YughInfo("Making sdf font %s.", fontfile); YughInfo("Making sdf font %s.", fontfile);
@ -99,10 +94,11 @@ struct sFont *MakeFont(const char *fontfile, int height) {
int ascent, descent, linegap; int ascent, descent, linegap;
stbtt_GetFontVMetrics(&fontinfo, &ascent, &descent, &linegap); stbtt_GetFontVMetrics(&fontinfo, &ascent, &descent, &linegap);
float emscale = tbtt_ScaleForMappingEmToPixels(&fontinfo, height); float emscale = stbtt_ScaleForMappingEmToPixels(&fontinfo, height);
newfont->ascent = ascent*emscale; newfont->ascent = ascent*emscale;
newfont->descent = descent*emscale; newfont->descent = descent*emscale;
newfont->linegap = linegap*emscale; newfont->linegap = linegap*emscale;
printf("ascent %g descent %g linegap %g\n", newfont->ascent, newfont->descent, newfont->linegap);
newfont->texture = malloc(sizeof(texture)); newfont->texture = malloc(sizeof(texture));
newfont->texture->id = sg_make_image(&(sg_image_desc){ newfont->texture->id = sg_make_image(&(sg_image_desc){
@ -129,6 +125,11 @@ struct sFont *MakeFont(const char *fontfile, int height) {
r.y = (glyph.y0) / (float)packsize; r.y = (glyph.y0) / (float)packsize;
r.h = (glyph.y1-glyph.y0) / (float)packsize; r.h = (glyph.y1-glyph.y0) / (float)packsize;
newfont->Characters[c].size = (HMM_Vec2){
.x = glyph.x1-glyph.x0,
.y = glyph.y1-glyph.y0
};
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */ newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
newfont->Characters[c].rect = r; newfont->Characters[c].rect = r;
} }
@ -139,27 +140,6 @@ struct sFont *MakeFont(const char *fontfile, int height) {
return newfont; return newfont;
} }
void draw_underline_cursor(HMM_Vec2 pos, float scale, struct rgba color)
{
pos.Y -= 2;
sdrawCharacter(use_font->Characters['_'], pos, scale, color);
}
void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color)
{
HMM_Vec2 wh;
color.a = 30;
wh.x = c.Size[0] * scale + 2;
wh.y = c.Size[1] * scale + 2;
cursor.X += c.Bearing[0] * scale + 1;
cursor.Y -= (c.Bearing[1] * scale + 1);
HMM_Vec2 b;
b.x = cursor.X + wh.x/2;
b.y = cursor.Y + wh.y/2;
}
int text_flush(sg_buffer *buf) { int text_flush(sg_buffer *buf) {
if (arrlen(text_buffer) == 0) return 0; if (arrlen(text_buffer) == 0) return 0;
@ -183,14 +163,11 @@ int text_flush(sg_buffer *buf) {
} }
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) { void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) {
struct rgba colorbox = {0,0,0,255};
struct text_vert vert; struct text_vert vert;
vert.pos.x = cursor.X + c.Bearing[0] * scale; vert.pos.x = cursor.X + c.leftbearing * scale;
vert.pos.y = cursor.Y - c.Bearing[1] * scale; vert.pos.y = cursor.Y - c.topbearing * scale;
vert.wh.x = c.\Size[0] * scale; vert.wh = c.size;
vert.wh.y = c.Size[1] * scale;
// if (vert.pos.x > frame.l || vert.pos.y > frame.t || (vert.pos.y + vert.wh.y) < frame.b || (vert.pos.x + vert.wh.x) < frame.l) return; // if (vert.pos.x > frame.l || vert.pos.y > frame.t || (vert.pos.y + vert.wh.y) < frame.b || (vert.pos.x + vert.wh.x) < frame.l) return;
@ -230,92 +207,71 @@ const char *esc_color(const char *c, struct rgba *color, struct rgba defc)
return c; return c;
} }
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking) // 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)
{ {
if (!use_font) return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){0,0}); HMM_Vec2 dim = {0};
struct rgba dummy; float maxWidth = 0; // max width of any line
HMM_Vec2 cursor = {0,0}; float lineWidth = 0; // current line width
const char *line, *wordstart; size = f->height;
line = text;
while (*line != '\0') { float scale = size/f->height;
if (isblank(*line)) { float lineHeight = f->ascent - f->descent;
cursor.X += use_font->Characters[*line].Advance * tracking * scale; lineHeight *= scale;
line++; letterSpacing *= scale;
} else if (isspace(*line)) {
cursor.Y -= scale * use_font->linegap;
cursor.X = 0;
line++;
} else {
if (*line == '\e')
line = esc_color(line, NULL, dummy);
wordstart = line; float height = lineHeight; // total height
int wordWidth = 0;
while (!isspace(*line) && *line != '\0') { for (char *c = text; *c != 0; c++) {
wordWidth += use_font->Characters[*line].Advance * tracking * scale; if (*c == '\n') {
line++; maxWidth = fmaxf(maxWidth, lineWidth);
} lineWidth = 0;
height += lineHeight + f->linegap;
if (lw > 0 && (cursor.X + wordWidth) >= lw) { continue;
cursor.X = 0;
cursor.Y -= scale * use_font->linegap;
}
while (wordstart < line) {
if (*wordstart == '\e')
line = esc_color(wordstart, NULL, dummy);
cursor.X += use_font->Characters[*wordstart].Advance * tracking * scale;
wordstart++;
}
} }
lineWidth += f->Characters[*c].Advance + letterSpacing;
} }
return (struct boundingbox){ maxWidth = fmaxf(maxWidth, lineWidth);
.b = cursor.Y + use_font->descent, dim.x = maxWidth;
.t = cursor.Y + use_font->ascent, dim.y = height;
.l = 0, return dim;
.r = cursor.X
};
}
void check_caret(int caret, int l, HMM_Vec2 pos, float scale, struct rgba color)
{
if (caret == l)
draw_underline_cursor(pos,scale,color);
} }
/* pos given in screen coordinates */ /* pos given in screen coordinates */
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking) { void renderText(const char *text, HMM_Vec2 pos, font *f, float scale, struct rgba color, float wrap) {
if (!use_font) {
YughError("Cannot render text before a font is set.");
return pos.y;
}
int len = strlen(text); int len = strlen(text);
HMM_Vec2 cursor = pos; HMM_Vec2 cursor = pos;
float lineHeight = f->ascent - f->descent;
for (char *c = text; *c != 0; c++) {
if (*c == '\n') {
cursor.x = pos.x;
cursor.y += lineHeight + f->linegap;
continue;
}
sdrawCharacter(f->Characters[*c], cursor, scale, color);
cursor.x += f->Characters[*c].Advance;
}
return;
const char *line, *wordstart, *drawstart; const char *line, *wordstart, *drawstart;
line = drawstart = text; line = drawstart = text;
struct rgba usecolor = color; struct rgba usecolor = color;
check_caret(caret, line-drawstart, cursor, scale, usecolor);
while (*line != '\0') { while (*line != '\0') {
if (isblank(*line)) { if (isblank(*line)) {
sdrawCharacter(use_font->Characters[*line], cursor, scale, usecolor); sdrawCharacter(f->Characters[*line], cursor, scale, usecolor);
cursor.X += use_font->Characters[*line].Advance * tracking * scale; cursor.X += f->Characters[*line].Advance * scale;
line++; line++;
check_caret(caret, line-drawstart, cursor, scale, usecolor);
} else if (isspace(*line)) { } else if (isspace(*line)) {
sdrawCharacter(use_font->Characters[*line], cursor, scale, usecolor); sdrawCharacter(f->Characters[*line], cursor, scale, usecolor);
cursor.Y -= scale * use_font->linegap; cursor.Y -= scale * f->linegap;
cursor.X = pos.X; cursor.X = pos.X;
line++; line++;
check_caret(caret, line-drawstart, cursor, scale, usecolor);
} else { } else {
if (*line == '\e') if (*line == '\e')
line = esc_color(line, &usecolor, color); line = esc_color(line, &usecolor, color);
@ -325,28 +281,25 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
while (!isspace(*line) && *line != '\0') { while (!isspace(*line) && *line != '\0') {
wordWidth += use_font->Characters[*line].Advance * tracking * scale; wordWidth += f->Characters[*line].Advance * scale;
line++; line++;
} }
if (lw > 0 && (cursor.X + wordWidth - pos.X) >= lw) { if (wrap > 0 && (cursor.X + wordWidth - pos.X) >= wrap) {
cursor.X = pos.X; cursor.X = pos.X;
cursor.Y -= scale * use_font->linegap; cursor.Y -= scale * f->linegap;
} }
while (wordstart < line) { while (wordstart < line) {
if (*wordstart == '\e') if (*wordstart == '\e')
wordstart = esc_color(wordstart, &usecolor, color); wordstart = esc_color(wordstart, &usecolor, color);
//sdrawCharacter(use_font->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255}); //sdrawCharacter(f->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
sdrawCharacter(use_font->Characters[*wordstart], cursor, scale, usecolor); sdrawCharacter(f->Characters[*wordstart], cursor, scale, usecolor);
cursor.X += use_font->Characters[*wordstart].Advance * tracking * scale; cursor.X += f->Characters[*wordstart].Advance * scale;
wordstart++; wordstart++;
check_caret(caret, wordstart-drawstart, cursor, scale, usecolor);
} }
} }
} }
return cursor.Y - pos.Y;
} }

View file

@ -12,10 +12,11 @@ extern sg_buffer text_ssbo;
/// Holds all state information relevant to a character as loaded using FreeType /// Holds all state information relevant to a character as loaded using FreeType
struct Character { struct Character {
int Advance; // Horizontal offset to advance to next glyph float Advance; // Horizontal offset to advance to next glyph
float leftbearing; // X offset from cursor to render at float leftbearing; // X offset from cursor to render at
float topbearing; // Y offset from cursor to render at float topbearing; // Y offset from cursor to render at
struct rect rect; // the rect on the font image to render from struct rect rect; // the rect on the font image to render from, uv coordinates
HMM_Vec2 size; // The pixel size of this letter
}; };
struct sFont { struct sFont {
@ -29,16 +30,16 @@ struct sFont {
}; };
typedef struct sFont font; typedef struct sFont font;
typedef struct Character glyph;
void font_free(font *f); void font_free(font *f);
struct sFont *MakeFont(const char *fontfile, int height); struct sFont *MakeFont(const char *fontfile, int height);
void font_set(font *f);
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color); void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color);
void text_settype(struct sFont *font); void renderText(const char *text, HMM_Vec2 pos, font *f, float scale, struct rgba color, float wrap);
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking); HMM_Vec2 measure_text(const char *text, font *f, float scale, float letterSpacing, float wrap);
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking);
// Flushes all letters from renderText calls into the provided buffer
int text_flush(sg_buffer *buf); int text_flush(sg_buffer *buf);
#endif #endif

View file

@ -788,7 +788,9 @@ JSC_CCALL(render_viewport,
JSC_CCALL(render_commit, sg_commit()) JSC_CCALL(render_commit, sg_commit())
JSC_CCALL(render_end_pass, sg_end_pass()) JSC_CCALL(render_end_pass, sg_end_pass())
JSC_SCALL(render_text_size, ret = bb2js(text_bb(str, js2number(argv[1]), js2number(argv[2]), 1))) JSC_SCALL(render_measure_text,
ret = vec22js(measure_text(str, js2font(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4])))
)
HMM_Mat4 transform2view(transform *t) HMM_Mat4 transform2view(transform *t)
{ {
@ -1263,7 +1265,7 @@ static const JSCFunctionListEntry js_render_funcs[] = {
MIST_FUNC_DEF(render, end_pass, 0), MIST_FUNC_DEF(render, end_pass, 0),
MIST_FUNC_DEF(render, commit, 0), MIST_FUNC_DEF(render, commit, 0),
MIST_FUNC_DEF(render, glue_pass, 0), MIST_FUNC_DEF(render, glue_pass, 0),
MIST_FUNC_DEF(render, text_size, 3), MIST_FUNC_DEF(render, measure_text, 5),
MIST_FUNC_DEF(render, set_camera, 1), MIST_FUNC_DEF(render, set_camera, 1),
MIST_FUNC_DEF(render, make_pipeline, 1), MIST_FUNC_DEF(render, make_pipeline, 1),
MIST_FUNC_DEF(render, setuniv3, 2), MIST_FUNC_DEF(render, setuniv3, 2),
@ -1387,25 +1389,18 @@ JSC_CCALL(gui_scissor,
sg_apply_scissor_rect(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0); sg_apply_scissor_rect(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0);
) )
JSC_CCALL(gui_text, JSC_SCALL(gui_text,
const char *s = JS_ToCString(js, argv[0]);
HMM_Vec2 pos = js2vec2(argv[1]); HMM_Vec2 pos = js2vec2(argv[1]);
float size = js2number(argv[2]); float size = js2number(argv[2]);
struct rgba c = js2color(argv[3]); struct rgba c = js2color(argv[3]);
int wrap = js2number(argv[4]); int wrap = js2number(argv[4]);
int cursor = js2number(argv[5]); font *f = js2font(argv[5]);
JSValue ret = JS_NewInt64(js, renderText(s, pos, size, c, wrap, cursor, 1.0)); renderText(str, pos, f, size, c, wrap);
JS_FreeCString(js, s);
return ret;
) )
JSC_CCALL(gui_font_set, font_set(js2font(argv[0])))
static const JSCFunctionListEntry js_gui_funcs[] = { static const JSCFunctionListEntry js_gui_funcs[] = {
MIST_FUNC_DEF(gui, scissor, 4), MIST_FUNC_DEF(gui, scissor, 4),
MIST_FUNC_DEF(gui, text, 6), MIST_FUNC_DEF(gui, text, 6),
MIST_FUNC_DEF(gui, font_set,1)
}; };
JSC_CCALL(spline_catmull, JSC_CCALL(spline_catmull,
@ -3818,15 +3813,18 @@ JSC_CCALL(clay_dimensions,
Clay_SetLayoutDimensions((Clay_Dimensions) { dim.x, dim.y }); Clay_SetLayoutDimensions((Clay_Dimensions) { dim.x, dim.y });
) )
static int container_id = 0;
JSC_CCALL(clay_draw, JSC_CCALL(clay_draw,
container_id = 0;
Clay_BeginLayout(); Clay_BeginLayout();
script_call_sym(argv[0], 0, NULL); script_call_sym(argv[0], 0, NULL);
Clay_RenderCommandArray cmd = Clay_EndLayout(); Clay_RenderCommandArray cmd = Clay_EndLayout();
ret = JS_NewArray(js); ret = JS_NewArray(js);
printf("there are %d commands here\n", cmd.length);
for (int i = 0; i < cmd.length; i++) { for (int i = 0; i < cmd.length; i++) {
Clay_RenderCommand cc = cmd.internalArray[i]; Clay_RenderCommand cc = cmd.internalArray[i];
if (cc.commandType == CLAY_RENDER_COMMAND_TYPE_NONE) continue;
JSValue c = JS_NewObject(js); JSValue c = JS_NewObject(js);
JSValue bb = JS_NewObject(js); JSValue bb = JS_NewObject(js);
js_setpropstr(bb, "x", number2js(cc.boundingBox.x)); js_setpropstr(bb, "x", number2js(cc.boundingBox.x));
@ -3835,9 +3833,29 @@ JSC_CCALL(clay_draw,
js_setpropstr(bb, "height", number2js(cc.boundingBox.height)); js_setpropstr(bb, "height", number2js(cc.boundingBox.height));
js_setpropstr(c, "boundingbox", bb); js_setpropstr(c, "boundingbox", bb);
js_setprop_num(ret, i, c); js_setprop_num(ret, i, c);
Clay_RectangleElementConfig *rect = cc.config.rectangleElementConfig;
js_setpropstr(c, "config", rect->js); switch(cc.commandType) {
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE:
Clay_RectangleElementConfig *rect = cc.config.rectangleElementConfig;
js_setpropstr(c, "config", JS_DupValue(js,rect->js));
break;
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START:
js_setpropstr(c, "config", str2js("scissor_start"));
break;
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_END:
js_setpropstr(c, "config", str2js('scissor_end'));
break;
}
} }
for (int i = 0; i < cmd.length; i++) {
Clay_RenderCommand cc = cmd.internalArray[i];
if (cc.commandType != CLAY_RENDER_COMMAND_TYPE_RECTANGLE) continue;
Clay_RectangleElementConfig *rect = cc.config.rectangleElementConfig;
if (!JS_IsUndefined(rect->js)) {
JS_FreeValue(js, rect->js);
rect->js = JS_UNDEFINED;
}
}
) )
JSC_CCALL(clay_pointer, JSC_CCALL(clay_pointer,
@ -3853,41 +3871,15 @@ JSC_CCALL(clay_updatescroll,
Clay_UpdateScrollContainers(drag, (Clay_Vector2){delta.x,delta.y}, dt); Clay_UpdateScrollContainers(drag, (Clay_Vector2){delta.x,delta.y}, dt);
) )
JSC_SCALL(clay_container, JSC_CCALL(clay_container,
Clay_LayoutConfig config = js2layout(argv[1]); Clay_LayoutConfig config = js2layout(argv[0]);
Clay_RectangleElementConfig rect = {0}; Clay_RectangleElementConfig rect = {0};
rect.js = JS_DupValue(js, argv[1]); rect.js = JS_DupValue(js, argv[0]);
Clay_String cstr; Clay__OpenRectangleElement(CLAY_IDI_LOCAL("container", container_id++), &config, &rect);
cstr.length = strlen(str); script_call_sym(argv[1], 0, NULL);
cstr.chars = str;
// Clay__OpenRectangleElement(Clay__HashString(cstr,0,0), &config, &rect);
Clay__OpenRectangleElement(CLAY_ID("TEST"), &config, &rect);
script_call_sym(argv[2], 0, NULL);
Clay__CloseElementWithChildren(); Clay__CloseElementWithChildren();
) )
JSC_SCALL(clay_image,
Clay_LayoutConfig config = js2layout(argv[1]);
Clay_ImageElementConfig image = {0};
HMM_Vec2 dim = js2vec2(argv[2]);
image.sourceDimensions.width = dim.x;
image.sourceDimensions.height = dim.y;
Clay__OpenImageElement(CLAY_ID(str), &config, &image);
script_call_sym(argv[3], 0, NULL);
Clay__CloseElementWithChildren();
)
JSC_SSCALL(clay_text,
Clay_TextElementConfig text = {0};
text.fontSize = js2number(js_getpropstr(argv[2], "font_size"));
text.letterSpacing = js2number(js_getpropstr(argv[2], "letter_spacing"));
text.lineHeight = js2number(js_getpropstr(argv[2], "line_spacing"));
text.wrapMode = (Clay_TextElementConfigWrapMode)js2number(js_getpropstr(argv[2], "wrap"));
text.font = js2font(js_getpropstr(argv[2], "font"));
Clay__OpenTextElement(CLAY_ID(str), CLAY_STRING(str2), &text);
// CLAY_TEXT(CLAY_ID(str), CLAY_STRING(str2), text)
)
JSC_SCALL(clay_scroll, JSC_SCALL(clay_scroll,
Clay_LayoutConfig config = js2layout(argv[1]); Clay_LayoutConfig config = js2layout(argv[1]);
Clay_ScrollElementConfig scroll = {0}; Clay_ScrollElementConfig scroll = {0};
@ -3926,32 +3918,11 @@ static const JSCFunctionListEntry js_clay_funcs[] = {
MIST_FUNC_DEF(clay, draw, 1), MIST_FUNC_DEF(clay, draw, 1),
MIST_FUNC_DEF(clay, pointer, 2), MIST_FUNC_DEF(clay, pointer, 2),
MIST_FUNC_DEF(clay, updatescroll, 3), MIST_FUNC_DEF(clay, updatescroll, 3),
MIST_FUNC_DEF(clay, container, 3), MIST_FUNC_DEF(clay, container, 2),
MIST_FUNC_DEF(clay, image, 4),
MIST_FUNC_DEF(clay, text, 3),
MIST_FUNC_DEF(clay, scroll, 3), MIST_FUNC_DEF(clay, scroll, 3),
MIST_FUNC_DEF(clay, floating, 3), MIST_FUNC_DEF(clay, floating, 3),
}; };
// Example measure text function
static inline Clay_Dimensions MeasureText(Clay_String *text, Clay_TextElementConfig *config) {
// Clay_TextElementConfig contains members such as fontId, fontSize, letterSpacing etc
// Note: Clay_String->chars is not guaranteed to be null terminated
Clay_Dimensions size = {0};
float maxWidth = 0;
float lineWidth = 0;
float height = config->font->height;
float scale = config->fontSize/height;
float lineHeight = config->font->ascent + config->font->descent + config->font->linegap;
lineHeight *= config->lineHeight * scale;
float letterSpacing = config->letterSpacing * scale;
for (int i = 0; i < text->length; i++) {
}
}
#include "steam.h" #include "steam.h"
#define JSSTATIC(NAME, PARENT) \ #define JSSTATIC(NAME, PARENT) \
@ -4006,7 +3977,6 @@ void ffi_load() {
uint64_t totalMemorySize = Clay_MinMemorySize(); uint64_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize)); Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
Clay_Initialize(arena, (Clay_Dimensions) { 1920, 1080 }); Clay_Initialize(arena, (Clay_Dimensions) { 1920, 1080 });
Clay_SetMeasureTextFunction(MeasureText);
QJSGLOBALCLASS(clay); QJSGLOBALCLASS(clay);
QJSGLOBALCLASS(poly2d); QJSGLOBALCLASS(poly2d);