diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 2dbbe73..545a33a 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -293,6 +293,16 @@ JSValue nk_rect2js(struct nk_rect rect) { return obj; } +JSValue bb2js(struct boundingbox bb) +{ + JSValue obj = JS_NewObject(js); + JS_SetPropertyStr(js,obj,"t", JS_NewFloat64(js,bb.t)); + JS_SetPropertyStr(js,obj,"b", JS_NewFloat64(js,bb.b)); + JS_SetPropertyStr(js,obj,"r", JS_NewFloat64(js,bb.r)); + JS_SetPropertyStr(js,obj,"l", JS_NewFloat64(js,bb.l)); + return obj; +} + JSValue duk_nuke(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { int cmd = js2int(argv[0]); float editnum; @@ -1027,6 +1037,11 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) str = JS_ToCString(js, argv[1]); ret = JS_NewInt64(js, script_runfile(str)); break; + + case 118: + str = JS_ToCString(js,argv[1]); + return bb2js(text_bb(str, js2number(argv[2]), js2number(argv[3]))); + break; } diff --git a/source/engine/font.c b/source/engine/font.c index 88205d4..f93f1b7 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -307,6 +307,47 @@ void text_settype(struct sFont *mfont) { font = mfont; } +struct boundingbox text_bb(const char *text, float scale, float lw) +{ + HMM_Vec2 cursor = {0,0}; + unsigned char *c = text; + unsigned char *wordstart; + + while (*c != '\0') { + if (isblank(*c)) { + cursor.X += font->Characters[*c].Advance * scale; + c++; + } else if (isspace(*c)) { + cursor.Y -= scale * font->height; + cursor.X = 0; + c++; + } else { + wordstart = c; + int wordwidth = 0; + + while (!isspace(*c) && *c != '\0') { + wordwidth += font->Characters[*c].Advance * scale; + c++; + } + + if (lw > 0 && (cursor.X + wordwidth) >= lw) { + cursor.X = 0; + cursor.Y -= scale * font->height; + } + + while (wordstart < c) { + cursor.X += font->Characters[*wordstart].Advance * scale; + wordstart++; + } + } + } + + float height = cursor.Y + (font->height*scale); + float width = lw > 0 ? lw : cursor.X; + + return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){width,height}); +} + int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret) { int len = strlen(text); drawcaret = caret; @@ -328,9 +369,7 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f cursor.Y -= scale * font->height; cursor.X = pos.X; line++; - } else { - wordstart = line; int wordWidth = 0; diff --git a/source/engine/font.h b/source/engine/font.h index 074017f..7b301a4 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -28,6 +28,7 @@ void font_init(struct shader *s); struct sFont *MakeFont(const char *fontfile, int height); void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color); void text_settype(struct sFont *font); +struct boundingbox text_bb(const char *text, float scale, float lw); int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret); // void text_frame(); diff --git a/source/engine/render.h b/source/engine/render.h index 1402fd8..977d863 100644 --- a/source/engine/render.h +++ b/source/engine/render.h @@ -6,6 +6,8 @@ #include "sokol/sokol_gfx.h" +#include "HandmadeMath.h" + struct uv_n { unsigned short u; unsigned short v; @@ -23,6 +25,24 @@ struct rgba { unsigned char a; }; +struct boundingbox { + float t; + float b; + float r; + float l; +}; + +static struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh) { + struct boundingbox bb = { + .t = c.Y + wh.Y/2, + .b = c.Y - wh.Y/2, + .r = c.X + wh.X/2, + .l = c.X - wh.X/2 + }; + + return bb; +} + static float *rgba2floats(float *r, struct rgba c) { r[0] = c.r / 255.0; diff --git a/source/scripts/engine.js b/source/scripts/engine.js index 27a76d4..8802053 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -138,8 +138,12 @@ var GUI = { text(str, pos, size, color, wrap) { size = size ? size : 1; color = color ? color : [255,255,255,255]; - wrap = wrap ? wrap : 500; - var h = ui_text(str, pos, size, color, wrap); + wrap = wrap ? wrap : -1; + + var bb = cmd(118, str, size, wrap); + var opos = [bb.r, bb.t]; + + var h = ui_text(str, pos.sub(opos), size, color, wrap); return [wrap,h]; }, @@ -147,6 +151,10 @@ var GUI = { text_cursor(str, pos, size, cursor) { cursor_text(str,pos,size,[255,255,255],cursor); }, + + column(items) { + items.forEach(x => x()); + }, }; function listbox(pos, item) {