Text fixes
This commit is contained in:
parent
c3daf57f24
commit
5e0966beb8
@ -14,18 +14,7 @@ static inline void immdraw_fill_rect(int16_t x, int16_t y, int16_t w, int16_t h,
|
||||
}
|
||||
|
||||
static inline void immdraw_font_draw(struct k3Font *font, int16_t x, int16_t y, int16_t w, float sz, size_t len, const char *txt, int alignment, float r, float g, float b, float a) {
|
||||
struct k3RectF txtsz;
|
||||
k3FontSz(font, sz, txt, w, &txtsz);
|
||||
|
||||
if(alignment != k3M_ALIGN_LEFT) {
|
||||
if(alignment == k3M_ALIGN_CENTER) {
|
||||
x += w / 2.0f - txtsz.w / 2.0f;
|
||||
} else {
|
||||
x += w - txtsz.w;
|
||||
}
|
||||
}
|
||||
|
||||
k3FontDraw(font, x, GameWndH - y - sz, sz, txt, w, (vec4) {r, g, b, a});
|
||||
k3FontDraw(font, x, GameWndH - y - sz, sz, txt, w, alignment, (vec4) {r, g, b, a});
|
||||
}
|
||||
static inline void immdraw_font_size(struct k3Font *font, float sz, const char *txt, int16_t wall, int16_t aabb[2]) {
|
||||
struct k3RectF txtsz;
|
||||
|
64
src/k3font.c
64
src/k3font.c
@ -108,7 +108,9 @@ void k3FontSz(struct k3Font *this, float sz, const char *txt, float wall, struct
|
||||
while(1) {
|
||||
uint32_t cp = read_utf8(&txt);
|
||||
|
||||
if(!cp) break;
|
||||
if(cp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(cp == 10) {
|
||||
x = 0;
|
||||
@ -119,7 +121,7 @@ void k3FontSz(struct k3Font *this, float sz, const char *txt, float wall, struct
|
||||
|
||||
if(!g) continue;
|
||||
|
||||
if(x + g->width > wall) {
|
||||
if(x + g->width * this->lineScale * sz > wall) {
|
||||
x = 0;
|
||||
y += sz;
|
||||
}
|
||||
@ -131,31 +133,57 @@ void k3FontSz(struct k3Font *this, float sz, const char *txt, float wall, struct
|
||||
ret->w = maxX;
|
||||
ret->h = y;
|
||||
}
|
||||
void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const char *txt, float wall, vec4 color) {
|
||||
void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const char *txt, float wall, int alignment, vec4 color) {
|
||||
if(wall < 0) {
|
||||
wall = HUGE_VALF;
|
||||
}
|
||||
|
||||
float x = xStart, y = yStart;
|
||||
float y = yStart;
|
||||
|
||||
while(1) {
|
||||
uint32_t cp = read_utf8(&txt);
|
||||
size_t lineLength = 0;
|
||||
|
||||
if(!cp) break;
|
||||
float lineWidth = 0;
|
||||
|
||||
if(cp == 10) {
|
||||
x = xStart;
|
||||
y -= sz;
|
||||
uint32_t cp2;
|
||||
const char *txt2 = txt;
|
||||
while(1) {
|
||||
cp2 = read_utf8(&txt2);
|
||||
if(cp2 == 0 || cp2 == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
lineLength++;
|
||||
|
||||
struct k3FontGlyph *g = k3FontGetGlyph(this, cp2);
|
||||
if(g) {
|
||||
if(lineWidth + g->width * this->lineScale * sz > wall) {
|
||||
break;
|
||||
}
|
||||
lineWidth += g->xadvance * this->lineScale * sz;
|
||||
}
|
||||
}
|
||||
|
||||
if(lineLength == 0 && cp2 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
float x = 0;
|
||||
if(alignment == 0) {
|
||||
x = xStart;
|
||||
} else if(alignment == 1) {
|
||||
x = xStart + (wall - lineWidth) / 2;
|
||||
} else if(alignment == 2) {
|
||||
x = xStart + wall - lineWidth;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < lineLength; i++) {
|
||||
uint32_t cp = read_utf8(&txt);
|
||||
|
||||
struct k3FontGlyph *g = k3FontGetGlyph(this, cp);
|
||||
|
||||
if(!g) continue;
|
||||
|
||||
if(x + g->width - xStart > wall) {
|
||||
x = xStart;
|
||||
y -= sz;
|
||||
}
|
||||
|
||||
struct k3Tex *tex = this->pages[g->page];
|
||||
size_t texW = this->texW;
|
||||
size_t texH = this->texH;
|
||||
@ -171,6 +199,14 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const
|
||||
|
||||
x += g->xadvance * this->lineScale * sz;
|
||||
}
|
||||
|
||||
// If the line break was caused directly by a LF, skip over it for next line
|
||||
if(cp2 == 10) {
|
||||
read_utf8(&txt);
|
||||
}
|
||||
|
||||
y -= sz;
|
||||
}
|
||||
k3BatchFlush();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include"k3batch.h"
|
||||
#include<string.h>
|
||||
|
||||
#define k3_FONT_ALIGN_LEFT 0
|
||||
#define k3_FONT_ALIGN_CENTER 1
|
||||
#define k3_FONT_ALIGN_RIGHT 2
|
||||
|
||||
struct k3FontGlyph {
|
||||
uint32_t cp;
|
||||
uint16_t x;
|
||||
@ -39,7 +43,7 @@ struct k3Font *k3FontCreate();
|
||||
int k3FontLoad(struct k3Font*, const uint8_t *buf, size_t len, k3FontTexLoader);
|
||||
|
||||
void k3FontSz(struct k3Font*, float sz, const char *txt, float wall, struct k3RectF *ret);
|
||||
void k3FontDraw(struct k3Font*, float x, float y, float sz, const char *txt, float wall, vec4 color);
|
||||
void k3FontDraw(struct k3Font*, float x, float y, float sz, const char *txt, float wall, int alignment, vec4 color);
|
||||
|
||||
struct k3FontGlyph *k3FontGetGlyph(struct k3Font*, uint32_t cp);
|
||||
|
||||
|
146
src/k3menu.c
146
src/k3menu.c
@ -54,6 +54,7 @@ static bool linear_measure(struct k3MEvent *ev, uint8_t *ud) {
|
||||
o->wDesired = 0;
|
||||
o->hDesired = 0;
|
||||
|
||||
intmax_t prevChildMargin[4] = {};
|
||||
for(size_t i = 0; i < o->childCount; i++) {
|
||||
struct k3MObj *c = o->children[i];
|
||||
|
||||
@ -61,7 +62,19 @@ static bool linear_measure(struct k3MEvent *ev, uint8_t *ud) {
|
||||
o->wDesired = c->wDesired;
|
||||
}
|
||||
|
||||
o->hDesired += c->hDesired;
|
||||
intmax_t margin[4] = {};
|
||||
struct k3MProperty *prop = k3MFindProperty(o, k3M_PROP_MARGIN, true);
|
||||
if(prop) {
|
||||
for(int s = 0; s < 4; s++) {
|
||||
if(prop->units[s] == k3M_UNIT_ABSOLUTE) {
|
||||
margin[s] = prop->f[s];
|
||||
} else if(prop->units[s] == k3M_UNIT_PROPORTION && o->parent) {
|
||||
margin[s] = prop->f[s] * (s % 2 == 0 ? o->h : o->w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o->hDesired += margin[0] + c->hDesired + margin[2];
|
||||
}
|
||||
}
|
||||
static bool linear_arrange(struct k3MEvent *ev, uint8_t *ud) {
|
||||
@ -87,7 +100,9 @@ static bool linear_arrange(struct k3MEvent *ev, uint8_t *ud) {
|
||||
c->x = o->x + padding[3];
|
||||
c->y = y;
|
||||
|
||||
if(c->w > o->w - padding[1] - padding[3]) {
|
||||
c->w = o->w - padding[1] - padding[3];
|
||||
}
|
||||
|
||||
if(!k3MEventSend(&(struct k3MEvent) {.original = o, .target = c, .code = k3M_EVENT_SET_HEIGHT_FROM_WIDTH})) {
|
||||
c->h = c->hDesired;
|
||||
@ -213,21 +228,48 @@ static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||
obj_draw_direct((void*) this);
|
||||
|
||||
if(this->txt) {
|
||||
int alignment = k3M_ALIGN_CENTER;
|
||||
|
||||
struct k3MProperty *propHA = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false);
|
||||
if(propHA) alignment = propHA->si[0];
|
||||
|
||||
float sz = this->sz;
|
||||
struct k3MProperty *fontSize = k3MFindProperty(this, k3M_PROP_FONT_SIZE, false);
|
||||
if(fontSize) sz = fontSize->f[0];
|
||||
struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_FONT_SIZE, false);
|
||||
if(prop) sz = prop->f[0];
|
||||
|
||||
immdraw_font_draw(this->font, this->x, this->y, this->w, sz, strlen(this->txt), this->txt, alignment,
|
||||
int ha = k3M_ALIGN_LEFT;
|
||||
prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false);
|
||||
if(prop) ha = prop->si[0];
|
||||
|
||||
int va = k3M_ALIGN_CENTER;
|
||||
prop = k3MFindProperty(this, k3M_PROP_VERTICAL_ALIGNMENT, false);
|
||||
if(prop) va = prop->si[0];
|
||||
|
||||
int16_t x = this->x;
|
||||
int16_t y = this->y;
|
||||
|
||||
if(va != k3M_ALIGN_TOP) {
|
||||
struct k3RectF txtsz;
|
||||
k3FontSz(this->font, this->sz, this->txt, this->w, &txtsz);
|
||||
if(va == k3M_ALIGN_CENTER) {
|
||||
y += (this->h - txtsz.h) / 2;
|
||||
} else if(va == k3M_ALIGN_BOTTOM) {
|
||||
y += this->h - txtsz.h;
|
||||
}
|
||||
}
|
||||
|
||||
immdraw_font_draw(this->font, x, y, this->w, sz, strlen(this->txt), this->txt, ha,
|
||||
1, 1, 1, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static bool label_measure(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MLabel *this = (void*) ev->target;
|
||||
|
||||
struct k3RectF txtsz;
|
||||
k3FontSz(this->font, this->sz, this->txt, -1, &txtsz);
|
||||
|
||||
this->w = ceilf(txtsz.w);
|
||||
this->h = ceilf(txtsz.h);
|
||||
|
||||
return false;
|
||||
}
|
||||
static bool label_set_height_from_width(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MLabel *this = (void*) ev->target;
|
||||
|
||||
@ -245,12 +287,9 @@ struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) {
|
||||
ret->txt = strdup(txt);
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_MEASURE, label_measure, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_SET_HEIGHT_FROM_WIDTH, label_set_height_from_width, NULL, 0);
|
||||
|
||||
//int16_t lblsz[2];
|
||||
//immdraw_font_size(font, sz, txt, lblsz);
|
||||
//ret->w = lblsz[0];
|
||||
//ret->h = lblsz[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -379,16 +418,22 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
|
||||
this->keyboardFocus = innermost;
|
||||
}
|
||||
|
||||
ev->kind = k3M_EVENTKIND_BUBBLE;
|
||||
ev->target = innermost;
|
||||
k3MEventSend(ev);
|
||||
k3MEventSend(&(struct k3MEvent) {
|
||||
.code = ev->code,
|
||||
.kind = k3M_EVENTKIND_BUBBLE,
|
||||
.original = ev->original,
|
||||
.target = innermost,
|
||||
.mouse = ev->mouse,
|
||||
});
|
||||
|
||||
if(ev->code == k3M_EVENT_MOUSE_RELEASE) {
|
||||
ev->code = k3M_EVENT_MOUSE_CLICK;
|
||||
|
||||
ev->kind = k3M_EVENTKIND_DIRECT;
|
||||
ev->target = innermost;
|
||||
k3MEventSend(ev);
|
||||
k3MEventSend(&(struct k3MEvent) {
|
||||
.code = k3M_EVENT_MOUSE_CLICK,
|
||||
.kind = k3M_EVENTKIND_DIRECT,
|
||||
.original = ev->original,
|
||||
.target = innermost,
|
||||
.mouse = ev->mouse,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -397,20 +442,25 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
|
||||
} else if(ev->code == k3M_EVENT_KEY_PRESS || ev->code == k3M_EVENT_KEY_RELEASE || ev->code == k3M_EVENT_INPUT) {
|
||||
|
||||
if(this->keyboardFocus) {
|
||||
ev->kind = k3M_EVENTKIND_BUBBLE;
|
||||
ev->target = (void*) this->keyboardFocus;
|
||||
k3MEventSend(ev);
|
||||
k3MEventSend(&(struct k3MEvent) {
|
||||
.code = ev->code,
|
||||
.kind = k3M_EVENTKIND_BUBBLE,
|
||||
.original = ev->original,
|
||||
.target = this->keyboardFocus,
|
||||
.key = ev->key,
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
ev->kind = k3M_EVENTKIND_CAPTURE;
|
||||
for(intmax_t i = this->childCount - 1; i >= 0; i--) {
|
||||
if(!this->children[i]->invisible) {
|
||||
ev->target = this->children[i];
|
||||
if(k3MEventSend(ev)) {
|
||||
struct k3MEvent newev = *ev;
|
||||
newev.kind = k3M_EVENTKIND_CAPTURE;
|
||||
newev.target = this->children[i];
|
||||
if(k3MEventSend(&newev)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -492,23 +542,44 @@ static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||
obj_draw_direct((void*) this);
|
||||
|
||||
if(this->txt) {
|
||||
/*struct k3RectF txtsz;
|
||||
k3FontSz(this->font, this->sz, this->txt, &txtsz);
|
||||
|
||||
k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) {
|
||||
1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1});*/
|
||||
|
||||
int alignment = k3M_ALIGN_CENTER;
|
||||
|
||||
int ha = k3M_ALIGN_CENTER;
|
||||
struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false);
|
||||
if(prop) alignment = prop->si[0];
|
||||
if(prop) ha = prop->si[0];
|
||||
|
||||
immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(this->txt), this->txt, alignment,
|
||||
int va = k3M_ALIGN_CENTER;
|
||||
prop = k3MFindProperty(this, k3M_PROP_VERTICAL_ALIGNMENT, false);
|
||||
if(prop) va = prop->si[0];
|
||||
|
||||
int16_t x = this->x;
|
||||
int16_t y = this->y;
|
||||
|
||||
if(va != k3M_ALIGN_TOP) {
|
||||
struct k3RectF txtsz;
|
||||
k3FontSz(this->font, this->sz, this->txt, this->w, &txtsz);
|
||||
if(va == k3M_ALIGN_CENTER) {
|
||||
y += (this->h - txtsz.h) / 2;
|
||||
} else if(va == k3M_ALIGN_BOTTOM) {
|
||||
y += this->h - txtsz.h;
|
||||
}
|
||||
}
|
||||
|
||||
immdraw_font_draw(this->font, x, y, this->w, this->sz, strlen(this->txt), this->txt, ha,
|
||||
1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static bool textbutton_measure(struct k3MEvent *ev, uint8_t *ud) {
|
||||
struct k3MTextButton *this = (void*) ev->target;
|
||||
|
||||
struct k3RectF sz = {};
|
||||
k3FontSz(this->font, this->sz, this->txt, -1, &sz);
|
||||
|
||||
this->w = ceilf(sz.w);
|
||||
this->h = ceilf(sz.h);
|
||||
|
||||
return false;
|
||||
}
|
||||
struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *txt) {
|
||||
struct k3MTextButton *ret = calloc(1, sizeof(*ret));
|
||||
|
||||
@ -516,6 +587,7 @@ struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *t
|
||||
ret->sz = sz;
|
||||
ret->txt = strdup(txt);
|
||||
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_MEASURE, textbutton_measure, NULL, 0);
|
||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0);
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user