use libgrapheme to interpret utf8 encoded strings

This commit is contained in:
Alessandro Mauri 2024-12-14 01:06:58 +01:00
parent 8cf3881b6b
commit 0db858e814
6 changed files with 84 additions and 45 deletions

View file

@ -1,6 +1,22 @@
module ugui;
import std::io;
import std::ascii;
import grapheme;
<*
@require off != null
*>
fn Codepoint str_to_codepoint(char[] str, usz* off)
{
Codepoint cp;
isz b = grapheme::decode_utf8(str, str.len, &cp);
if (b == 0 || b > str.len) {
return 0;
}
*off = b;
return cp;
}
fn Rect! Ctx.get_text_bounds(&ctx, String text, bool* update_atlas)
{
@ -12,16 +28,20 @@ fn Rect! Ctx.get_text_bounds(&ctx, String text, bool* update_atlas)
// TODO: account for unicode codepoints
short line_len;
foreach (c: text) {
Codepoint cp = (Codepoint)c;
Codepoint cp;
usz off, x;
while ((cp = str_to_codepoint(text[off..], &x)) != 0) {
off += x;
bool n;
if (cp != '\n') {
if (!ascii::is_cntrl((char)cp)) {
gp = ctx.font.get_glyph(cp, &n)!;
line_len += gp.adv;
if (n) { *update_atlas = true; }
} else {
} else if (cp == '\n'){
text_bounds.h += line_height + line_gap;
line_len = 0;
} else {
continue;
}
if (line_len > text_bounds.w) {
text_bounds.w = line_len;
@ -79,33 +99,5 @@ fn void! Ctx.text_unbounded(&ctx, String label, String text)
};
ctx.cmd_queue.enqueue(&bounds)!;
Point orig = {
.x = c_elem.bounds.x,
.y = c_elem.bounds.y,
};
short line_len;
foreach (c: text) {
Glyph* gp;
Codepoint cp = (Codepoint)c;
if (cp != '\n') {
gp = ctx.font.get_glyph(cp)!;
Rect gb = {
.x = orig.x + line_len + gp.ox,
.y = orig.y + gp.oy + baseline,
.w = gp.w,
.h = gp.h,
};
Rect gt = {
.x = gp.u,
.y = gp.v,
.w = gp.w,
.h = gp.h,
};
ctx.push_sprite(gb, gt)!;
line_len += gp.adv;
} else {
orig.y += line_height + line_gap;
line_len = 0;
}
}
ctx.push_string(c_elem.bounds, text)!;
}