From ba7fd6560e9f334b90a397f087aba08270e6ef47 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 30 May 2023 20:41:02 +0000 Subject: [PATCH] text positioning --- source/engine/ffi.c | 8 +++---- source/engine/font.c | 44 +++++++++++++++++++++---------------- source/engine/font.h | 12 ++++++---- source/scripts/engine.js | 20 ++++++++++++----- source/shaders/crtfrag.glsl | 2 ++ 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 545a33a..39051b7 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -236,7 +236,7 @@ JSValue duk_gui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *a HMM_Vec2 pos = js2hmmv2(argv[1]); float size = js2number(argv[2]); - renderText(s, pos, size, color_white, 500, -1); + renderText(s, pos, size, color_white, 500, -1, 1.0); JS_FreeCString(js, s); return JS_NULL; } @@ -248,7 +248,7 @@ JSValue duk_ui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *ar float size = js2number(argv[2]); struct rgba c = js2color(argv[3]); int wrap = js2int(argv[4]); - JSValue ret = JS_NewInt64(js, renderText(s, pos, size, c, wrap, -1)); + JSValue ret = JS_NewInt64(js, renderText(s, pos, size, c, wrap, -1, 1.0)); JS_FreeCString(js, s); return ret; } @@ -261,7 +261,7 @@ JSValue duk_cursor_text(JSContext *js, JSValueConst this, int argc, JSValueConst struct rgba c = js2color(argv[3]); int wrap = js2int(argv[5]); int cursor = js2int(argv[4]); - renderText(s, pos, size, c, wrap, cursor); + renderText(s, pos, size, c, wrap, cursor, 1.0); JS_FreeCString(js, s); return JS_NULL; } @@ -1040,7 +1040,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 118: str = JS_ToCString(js,argv[1]); - return bb2js(text_bb(str, js2number(argv[2]), js2number(argv[3]))); + return bb2js(text_bb(str, js2number(argv[2]), js2number(argv[3]), 1.0)); break; } diff --git a/source/engine/font.c b/source/engine/font.c index f93f1b7..2c9f8c1 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -189,6 +189,10 @@ struct sFont *MakeFont(const char *fontfile, int height) { YughError("Failed to make font %s", fontfile); } + stbtt_GetFontVMetrics(&fontinfo, &newfont->ascent, &newfont->descent, &newfont->linegap); + float emscale = stbtt_ScaleForMappingEmToPixels(&fontinfo, 16); + newfont->linegap = (newfont->ascent - newfont->descent)* 2 * emscale; + newfont->texID = sg_make_image(&(sg_image_desc){ .type = SG_IMAGETYPE_2D, .width = packsize, @@ -213,8 +217,12 @@ struct sFont *MakeFont(const char *fontfile, int height) { r.t0 = (glyph.y0) / (float)packsize; r.t1 = (glyph.y1) / (float)packsize; - newfont->Characters[c].Advance = glyph.xadvance; - newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0; + stbtt_GetCodepointHMetrics(&fontinfo, c, &newfont->Characters[c].Advance, &newfont->Characters[c].leftbearing); + newfont->Characters[c].Advance *= emscale; + newfont->Characters[c].leftbearing *= emscale; + +// newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */ + newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0; newfont->Characters[c].Size[1] = glyph.y1 - glyph.y0; newfont->Characters[c].Bearing[0] = glyph.xoff; newfont->Characters[c].Bearing[1] = glyph.yoff2; @@ -256,16 +264,14 @@ void text_flush() { static int drawcaret = 0; void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) { - HMM_Vec2 offset = {0.0}; - struct text_vert vert; float lsize = 1.0 / 1024.0; float oline = 1.0; - vert.pos.x = cursor.X - (c.Bearing[0] + offset.X) * scale - oline; - vert.pos.y = cursor.Y - (c.Bearing[1] + offset.Y) * scale - oline; + vert.pos.x = cursor.X + c.Bearing[0] * scale + oline; + vert.pos.y = cursor.Y - c.Bearing[1] * scale - oline; vert.wh.x = c.Size[0] * scale + (oline*2); vert.wh.y = c.Size[1] * scale + (oline*2); vert.uv.u = (c.rect.s0 - oline*lsize)*USHRT_MAX; @@ -307,7 +313,7 @@ void text_settype(struct sFont *mfont) { font = mfont; } -struct boundingbox text_bb(const char *text, float scale, float lw) +struct boundingbox text_bb(const char *text, float scale, float lw, float tracking) { HMM_Vec2 cursor = {0,0}; unsigned char *c = text; @@ -315,10 +321,10 @@ struct boundingbox text_bb(const char *text, float scale, float lw) while (*c != '\0') { if (isblank(*c)) { - cursor.X += font->Characters[*c].Advance * scale; + cursor.X += font->Characters[*c].Advance * tracking * scale; c++; } else if (isspace(*c)) { - cursor.Y -= scale * font->height; + cursor.Y -= scale * font->linegap; cursor.X = 0; c++; } else { @@ -326,29 +332,29 @@ struct boundingbox text_bb(const char *text, float scale, float lw) int wordwidth = 0; while (!isspace(*c) && *c != '\0') { - wordwidth += font->Characters[*c].Advance * scale; + wordwidth += font->Characters[*c].Advance * tracking * scale; c++; } if (lw > 0 && (cursor.X + wordwidth) >= lw) { cursor.X = 0; - cursor.Y -= scale * font->height; + cursor.Y -= scale * font->linegap; } while (wordstart < c) { - cursor.X += font->Characters[*wordstart].Advance * scale; + cursor.X += font->Characters[*wordstart].Advance * tracking * scale; wordstart++; } } } - float height = cursor.Y + (font->height*scale); + float height = cursor.Y + (font->linegap*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 renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking) { int len = strlen(text); drawcaret = caret; @@ -362,11 +368,11 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f while (*line != '\0') { if (isblank(*line)) { sdrawCharacter(font->Characters[*line], cursor, scale, usecolor); - cursor.X += font->Characters[*line].Advance * scale; + cursor.X += font->Characters[*line].Advance * tracking * scale; line++; } else if (isspace(*line)) { sdrawCharacter(font->Characters[*line], cursor, scale, usecolor); - cursor.Y -= scale * font->height; + cursor.Y -= scale * font->linegap; cursor.X = pos.X; line++; } else { @@ -374,18 +380,18 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f int wordWidth = 0; while (!isspace(*line) && *line != '\0') { - wordWidth += font->Characters[*line].Advance * scale; + wordWidth += font->Characters[*line].Advance * tracking * scale; line++; } if (lw > 0 && (cursor.X + wordWidth - pos.X) >= lw) { cursor.X = pos.X; - cursor.Y -= scale * font->height; + cursor.Y -= scale * font->linegap; } while (wordstart < line) { sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor); - cursor.X += font->Characters[*wordstart].Advance * scale; + cursor.X += font->Characters[*wordstart].Advance * tracking * scale; wordstart++; } } diff --git a/source/engine/font.h b/source/engine/font.h index 7b301a4..a9d9a2b 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -13,13 +13,17 @@ struct window; struct Character { float Size[2]; // Size of glyph float Bearing[2]; // Offset from baseline to left/top of glyph - unsigned int Advance; // Horizontal offset to advance to next glyph + int Advance; // Horizontal offset to advance to next glyph + int leftbearing; struct glrect rect; }; struct sFont { uint32_t fontTexture; - uint32_t height; + uint32_t height; /* in pixels */ + int ascent; + int descent; + int linegap; struct Character Characters[127]; sg_image texID; }; @@ -28,8 +32,8 @@ 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); +struct boundingbox text_bb(const char *text, float scale, float lw, float tracking); +int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking); // void text_frame(); void text_flush(); diff --git a/source/scripts/engine.js b/source/scripts/engine.js index 8802053..3a37e82 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -145,15 +145,23 @@ var GUI = { var h = ui_text(str, pos.sub(opos), size, color, wrap); - return [wrap,h]; + return bb; }, text_cursor(str, pos, size, cursor) { cursor_text(str,pos,size,[255,255,255],cursor); }, - column(items) { - items.forEach(x => x()); + image(path,pos) { + gui_img(path,screen2world(pos)); + return cwh2bb([0,0], cmd(64,path)); + }, + + column(items,pos) { + items.forEach(function(item) { + let bb = item(pos); + pos.y += bb.b; + }); }, }; @@ -405,8 +413,8 @@ var Input = { setnuke() { cmd(78); }, }; -function screen2world(screenpos) { return editor.camera.view2world(screenpos); } -function world2screen(worldpos) { return editor.camera.world2view(worldpos); } +function screen2world(screenpos) { return Yugine.camera.view2world(screenpos); } +function world2screen(worldpos) { return Yugine.camera.world2view(worldpos); } var physics = { set gravity(x) { cmd(8, x); }, @@ -1793,6 +1801,8 @@ var camera2d = gameobject.clone("camera2d", { }, }); +Yugine.camera = World.spawn(camera2d); + win_make(Game.title, Game.resolution[0], Game.resolution[1]); //win_icon("icon.png"); diff --git a/source/shaders/crtfrag.glsl b/source/shaders/crtfrag.glsl index 019971f..9d2a032 100644 --- a/source/shaders/crtfrag.glsl +++ b/source/shaders/crtfrag.glsl @@ -7,6 +7,8 @@ uniform sampler2D diffuse_texture; void main() { + frag_color = texture(diffuse_texture, TexCoords); + return; vec2 screensize = textureSize(diffuse_texture,0); vec4 color = texture(diffuse_texture, TexCoords);