text positioning
This commit is contained in:
parent
5f3bbbc582
commit
ba7fd6560e
|
@ -236,7 +236,7 @@ JSValue duk_gui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
||||||
HMM_Vec2 pos = js2hmmv2(argv[1]);
|
HMM_Vec2 pos = js2hmmv2(argv[1]);
|
||||||
|
|
||||||
float size = js2number(argv[2]);
|
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);
|
JS_FreeCString(js, s);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ JSValue duk_ui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
||||||
float size = js2number(argv[2]);
|
float size = js2number(argv[2]);
|
||||||
struct rgba c = js2color(argv[3]);
|
struct rgba c = js2color(argv[3]);
|
||||||
int wrap = js2int(argv[4]);
|
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);
|
JS_FreeCString(js, s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ JSValue duk_cursor_text(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
struct rgba c = js2color(argv[3]);
|
struct rgba c = js2color(argv[3]);
|
||||||
int wrap = js2int(argv[5]);
|
int wrap = js2int(argv[5]);
|
||||||
int cursor = js2int(argv[4]);
|
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);
|
JS_FreeCString(js, s);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1040,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
|
|
||||||
case 118:
|
case 118:
|
||||||
str = JS_ToCString(js,argv[1]);
|
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;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,10 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
YughError("Failed to make font %s", fontfile);
|
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){
|
newfont->texID = sg_make_image(&(sg_image_desc){
|
||||||
.type = SG_IMAGETYPE_2D,
|
.type = SG_IMAGETYPE_2D,
|
||||||
.width = packsize,
|
.width = packsize,
|
||||||
|
@ -213,8 +217,12 @@ struct sFont *MakeFont(const char *fontfile, int height) {
|
||||||
r.t0 = (glyph.y0) / (float)packsize;
|
r.t0 = (glyph.y0) / (float)packsize;
|
||||||
r.t1 = (glyph.y1) / (float)packsize;
|
r.t1 = (glyph.y1) / (float)packsize;
|
||||||
|
|
||||||
newfont->Characters[c].Advance = glyph.xadvance;
|
stbtt_GetCodepointHMetrics(&fontinfo, c, &newfont->Characters[c].Advance, &newfont->Characters[c].leftbearing);
|
||||||
newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0;
|
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].Size[1] = glyph.y1 - glyph.y0;
|
||||||
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
newfont->Characters[c].Bearing[0] = glyph.xoff;
|
||||||
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
newfont->Characters[c].Bearing[1] = glyph.yoff2;
|
||||||
|
@ -256,16 +264,14 @@ void text_flush() {
|
||||||
static int drawcaret = 0;
|
static int drawcaret = 0;
|
||||||
|
|
||||||
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) {
|
||||||
HMM_Vec2 offset = {0.0};
|
|
||||||
|
|
||||||
struct text_vert vert;
|
struct text_vert vert;
|
||||||
|
|
||||||
float lsize = 1.0 / 1024.0;
|
float lsize = 1.0 / 1024.0;
|
||||||
|
|
||||||
float oline = 1.0;
|
float oline = 1.0;
|
||||||
|
|
||||||
vert.pos.x = cursor.X - (c.Bearing[0] + offset.X) * scale - oline;
|
vert.pos.x = cursor.X + c.Bearing[0] * scale + oline;
|
||||||
vert.pos.y = cursor.Y - (c.Bearing[1] + offset.Y) * scale - oline;
|
vert.pos.y = cursor.Y - c.Bearing[1] * scale - oline;
|
||||||
vert.wh.x = c.Size[0] * scale + (oline*2);
|
vert.wh.x = c.Size[0] * scale + (oline*2);
|
||||||
vert.wh.y = c.Size[1] * scale + (oline*2);
|
vert.wh.y = c.Size[1] * scale + (oline*2);
|
||||||
vert.uv.u = (c.rect.s0 - oline*lsize)*USHRT_MAX;
|
vert.uv.u = (c.rect.s0 - oline*lsize)*USHRT_MAX;
|
||||||
|
@ -307,7 +313,7 @@ void text_settype(struct sFont *mfont) {
|
||||||
font = 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};
|
HMM_Vec2 cursor = {0,0};
|
||||||
unsigned char *c = text;
|
unsigned char *c = text;
|
||||||
|
@ -315,10 +321,10 @@ struct boundingbox text_bb(const char *text, float scale, float lw)
|
||||||
|
|
||||||
while (*c != '\0') {
|
while (*c != '\0') {
|
||||||
if (isblank(*c)) {
|
if (isblank(*c)) {
|
||||||
cursor.X += font->Characters[*c].Advance * scale;
|
cursor.X += font->Characters[*c].Advance * tracking * scale;
|
||||||
c++;
|
c++;
|
||||||
} else if (isspace(*c)) {
|
} else if (isspace(*c)) {
|
||||||
cursor.Y -= scale * font->height;
|
cursor.Y -= scale * font->linegap;
|
||||||
cursor.X = 0;
|
cursor.X = 0;
|
||||||
c++;
|
c++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -326,29 +332,29 @@ struct boundingbox text_bb(const char *text, float scale, float lw)
|
||||||
int wordwidth = 0;
|
int wordwidth = 0;
|
||||||
|
|
||||||
while (!isspace(*c) && *c != '\0') {
|
while (!isspace(*c) && *c != '\0') {
|
||||||
wordwidth += font->Characters[*c].Advance * scale;
|
wordwidth += font->Characters[*c].Advance * tracking * scale;
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lw > 0 && (cursor.X + wordwidth) >= lw) {
|
if (lw > 0 && (cursor.X + wordwidth) >= lw) {
|
||||||
cursor.X = 0;
|
cursor.X = 0;
|
||||||
cursor.Y -= scale * font->height;
|
cursor.Y -= scale * font->linegap;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wordstart < c) {
|
while (wordstart < c) {
|
||||||
cursor.X += font->Characters[*wordstart].Advance * scale;
|
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
|
||||||
wordstart++;
|
wordstart++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float height = cursor.Y + (font->height*scale);
|
float height = cursor.Y + (font->linegap*scale);
|
||||||
float width = lw > 0 ? lw : cursor.X;
|
float width = lw > 0 ? lw : cursor.X;
|
||||||
|
|
||||||
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){width,height});
|
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);
|
int len = strlen(text);
|
||||||
drawcaret = caret;
|
drawcaret = caret;
|
||||||
|
|
||||||
|
@ -362,11 +368,11 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
||||||
while (*line != '\0') {
|
while (*line != '\0') {
|
||||||
if (isblank(*line)) {
|
if (isblank(*line)) {
|
||||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||||
cursor.X += font->Characters[*line].Advance * scale;
|
cursor.X += font->Characters[*line].Advance * tracking * scale;
|
||||||
line++;
|
line++;
|
||||||
} else if (isspace(*line)) {
|
} else if (isspace(*line)) {
|
||||||
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
sdrawCharacter(font->Characters[*line], cursor, scale, usecolor);
|
||||||
cursor.Y -= scale * font->height;
|
cursor.Y -= scale * font->linegap;
|
||||||
cursor.X = pos.X;
|
cursor.X = pos.X;
|
||||||
line++;
|
line++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -374,18 +380,18 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
||||||
int wordWidth = 0;
|
int wordWidth = 0;
|
||||||
|
|
||||||
while (!isspace(*line) && *line != '\0') {
|
while (!isspace(*line) && *line != '\0') {
|
||||||
wordWidth += font->Characters[*line].Advance * scale;
|
wordWidth += font->Characters[*line].Advance * tracking * scale;
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lw > 0 && (cursor.X + wordWidth - pos.X) >= lw) {
|
if (lw > 0 && (cursor.X + wordWidth - pos.X) >= lw) {
|
||||||
cursor.X = pos.X;
|
cursor.X = pos.X;
|
||||||
cursor.Y -= scale * font->height;
|
cursor.Y -= scale * font->linegap;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wordstart < line) {
|
while (wordstart < line) {
|
||||||
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor);
|
sdrawCharacter(font->Characters[*wordstart], cursor, scale, usecolor);
|
||||||
cursor.X += font->Characters[*wordstart].Advance * scale;
|
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
|
||||||
wordstart++;
|
wordstart++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,17 @@ struct window;
|
||||||
struct Character {
|
struct Character {
|
||||||
float Size[2]; // Size of glyph
|
float Size[2]; // Size of glyph
|
||||||
float Bearing[2]; // Offset from baseline to left/top 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 glrect rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sFont {
|
struct sFont {
|
||||||
uint32_t fontTexture;
|
uint32_t fontTexture;
|
||||||
uint32_t height;
|
uint32_t height; /* in pixels */
|
||||||
|
int ascent;
|
||||||
|
int descent;
|
||||||
|
int linegap;
|
||||||
struct Character Characters[127];
|
struct Character Characters[127];
|
||||||
sg_image texID;
|
sg_image texID;
|
||||||
};
|
};
|
||||||
|
@ -28,8 +32,8 @@ void font_init(struct shader *s);
|
||||||
struct sFont *MakeFont(const char *fontfile, int height);
|
struct sFont *MakeFont(const char *fontfile, int height);
|
||||||
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 text_settype(struct sFont *font);
|
||||||
struct boundingbox text_bb(const char *text, float scale, float lw);
|
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);
|
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking);
|
||||||
|
|
||||||
// void text_frame();
|
// void text_frame();
|
||||||
void text_flush();
|
void text_flush();
|
||||||
|
|
|
@ -145,15 +145,23 @@ var GUI = {
|
||||||
|
|
||||||
var h = ui_text(str, pos.sub(opos), size, color, wrap);
|
var h = ui_text(str, pos.sub(opos), size, color, wrap);
|
||||||
|
|
||||||
return [wrap,h];
|
return bb;
|
||||||
},
|
},
|
||||||
|
|
||||||
text_cursor(str, pos, size, cursor) {
|
text_cursor(str, pos, size, cursor) {
|
||||||
cursor_text(str,pos,size,[255,255,255],cursor);
|
cursor_text(str,pos,size,[255,255,255],cursor);
|
||||||
},
|
},
|
||||||
|
|
||||||
column(items) {
|
image(path,pos) {
|
||||||
items.forEach(x => x());
|
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); },
|
setnuke() { cmd(78); },
|
||||||
};
|
};
|
||||||
|
|
||||||
function screen2world(screenpos) { return editor.camera.view2world(screenpos); }
|
function screen2world(screenpos) { return Yugine.camera.view2world(screenpos); }
|
||||||
function world2screen(worldpos) { return editor.camera.world2view(worldpos); }
|
function world2screen(worldpos) { return Yugine.camera.world2view(worldpos); }
|
||||||
|
|
||||||
var physics = {
|
var physics = {
|
||||||
set gravity(x) { cmd(8, x); },
|
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_make(Game.title, Game.resolution[0], Game.resolution[1]);
|
||||||
//win_icon("icon.png");
|
//win_icon("icon.png");
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ uniform sampler2D diffuse_texture;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
frag_color = texture(diffuse_texture, TexCoords);
|
||||||
|
return;
|
||||||
vec2 screensize = textureSize(diffuse_texture,0);
|
vec2 screensize = textureSize(diffuse_texture,0);
|
||||||
|
|
||||||
vec4 color = texture(diffuse_texture, TexCoords);
|
vec4 color = texture(diffuse_texture, TexCoords);
|
||||||
|
|
Loading…
Reference in a new issue