Adapt heightForWidth from Qt for text wrapping

This commit is contained in:
Mid 2025-08-28 23:34:05 +03:00
parent bf60cac302
commit c3daf57f24
5 changed files with 54 additions and 18 deletions

View File

@ -15,7 +15,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) { 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; struct k3RectF txtsz;
k3FontSz(font, sz, txt, &txtsz); k3FontSz(font, sz, txt, w, &txtsz);
if(alignment != k3M_ALIGN_LEFT) { if(alignment != k3M_ALIGN_LEFT) {
if(alignment == k3M_ALIGN_CENTER) { if(alignment == k3M_ALIGN_CENTER) {
@ -25,11 +25,11 @@ static inline void immdraw_font_draw(struct k3Font *font, int16_t x, int16_t y,
} }
} }
k3FontDraw(font, x, GameWndH - y - sz, sz, txt, (vec4) {r, g, b, a}); k3FontDraw(font, x, GameWndH - y - sz, sz, txt, w, (vec4) {r, g, b, a});
} }
static inline void immdraw_font_size(struct k3Font *font, float sz, const char *txt, int16_t aabb[2]) { static inline void immdraw_font_size(struct k3Font *font, float sz, const char *txt, int16_t wall, int16_t aabb[2]) {
struct k3RectF txtsz; struct k3RectF txtsz;
k3FontSz(font, sz, txt, &txtsz); k3FontSz(font, sz, txt, wall, &txtsz);
aabb[0] = ceilf(txtsz.w); aabb[0] = ceilf(txtsz.w);
aabb[1] = ceilf(txtsz.h); aabb[1] = ceilf(txtsz.h);

View File

@ -97,7 +97,13 @@ static uint32_t read_utf8(const char **txt_) {
} }
} }
void k3FontSz(struct k3Font *this, float sz, const char *txt, struct k3RectF *ret) { void k3FontSz(struct k3Font *this, float sz, const char *txt, float wall, struct k3RectF *ret) {
if(wall < 0) {
wall = HUGE_VALF;
}
float maxX = 0;
float x = 0, y = sz; float x = 0, y = sz;
while(1) { while(1) {
uint32_t cp = read_utf8(&txt); uint32_t cp = read_utf8(&txt);
@ -113,12 +119,23 @@ void k3FontSz(struct k3Font *this, float sz, const char *txt, struct k3RectF *re
if(!g) continue; if(!g) continue;
x += g->xadvance * this->lineScale * sz; if(x + g->width > wall) {
x = 0;
y += sz;
} }
ret->w = x;
x += g->xadvance * this->lineScale * sz;
maxX = fmaxf(maxX, x);
}
ret->w = maxX;
ret->h = y; ret->h = y;
} }
void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const char *txt, vec4 color) { void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const char *txt, float wall, vec4 color) {
if(wall < 0) {
wall = HUGE_VALF;
}
float x = xStart, y = yStart; float x = xStart, y = yStart;
while(1) { while(1) {
uint32_t cp = read_utf8(&txt); uint32_t cp = read_utf8(&txt);
@ -134,6 +151,11 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const
if(!g) continue; if(!g) continue;
if(x + g->width - xStart > wall) {
x = xStart;
y -= sz;
}
struct k3Tex *tex = this->pages[g->page]; struct k3Tex *tex = this->pages[g->page];
size_t texW = this->texW; size_t texW = this->texW;
size_t texH = this->texH; size_t texH = this->texH;

View File

@ -38,8 +38,8 @@ typedef struct k3Tex*(*k3FontTexLoader)(struct k3Font*, const char *name);
struct k3Font *k3FontCreate(); struct k3Font *k3FontCreate();
int k3FontLoad(struct k3Font*, const uint8_t *buf, size_t len, k3FontTexLoader); int k3FontLoad(struct k3Font*, const uint8_t *buf, size_t len, k3FontTexLoader);
void k3FontSz(struct k3Font*, float sz, const char *txt, struct k3RectF *ret); 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, vec4 color); void k3FontDraw(struct k3Font*, float x, float y, float sz, const char *txt, float wall, vec4 color);
struct k3FontGlyph *k3FontGetGlyph(struct k3Font*, uint32_t cp); struct k3FontGlyph *k3FontGetGlyph(struct k3Font*, uint32_t cp);

View File

@ -87,8 +87,11 @@ static bool linear_arrange(struct k3MEvent *ev, uint8_t *ud) {
c->x = o->x + padding[3]; c->x = o->x + padding[3];
c->y = y; c->y = y;
c->w = c->wDesired - 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; c->h = c->hDesired;
}
y += c->h; y += c->h;
} }
@ -225,7 +228,16 @@ static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
return false; return false;
} }
static bool label_set_height_from_width(struct k3MEvent *ev, uint8_t *ud) {
struct k3MLabel *this = (void*) ev->target;
int16_t pxsz[2];
immdraw_font_size(this->font, this->sz, this->txt, this->w, pxsz);
this->h = pxsz[1];
return true;
}
struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) { struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) {
struct k3MLabel *ret = calloc(1, sizeof(*ret)); struct k3MLabel *ret = calloc(1, sizeof(*ret));
ret->font = font; ret->font = font;
@ -233,11 +245,12 @@ struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) {
ret->txt = strdup(txt); ret->txt = strdup(txt);
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0); k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0);
k3MRegisterEventHandler(ret, k3M_EVENT_SET_HEIGHT_FROM_WIDTH, label_set_height_from_width, NULL, 0);
int16_t lblsz[2]; //int16_t lblsz[2];
immdraw_font_size(font, sz, txt, lblsz); //immdraw_font_size(font, sz, txt, lblsz);
ret->w = lblsz[0]; //ret->w = lblsz[0];
ret->h = lblsz[1]; //ret->h = lblsz[1];
return ret; return ret;
} }

View File

@ -22,7 +22,8 @@ struct k3MObj;
#define k3M_EVENT_MEASURE 11 #define k3M_EVENT_MEASURE 11
#define k3M_EVENT_ARRANGE 12 #define k3M_EVENT_ARRANGE 12
#define k3M_EVENT_POST_ARRANGE 13 #define k3M_EVENT_POST_ARRANGE 13
#define k3M_EVENT_ALL 14 #define k3M_EVENT_SET_HEIGHT_FROM_WIDTH 14
#define k3M_EVENT_ALL 15
#define k3M_MOUSE_BUTTON_0 0 #define k3M_MOUSE_BUTTON_0 0
#define k3M_MOUSE_BUTTON_1 1 #define k3M_MOUSE_BUTTON_1 1