diff --git a/game/res/textures/font_9x20.png b/game/res/textures/font_9x20.png index df17ae6..7a60e0e 100644 Binary files a/game/res/textures/font_9x20.png and b/game/res/textures/font_9x20.png differ diff --git a/game/res/textures/font_9x20.xcf b/game/res/textures/font_9x20.xcf index c41d918..fda6bd8 100644 Binary files a/game/res/textures/font_9x20.xcf and b/game/res/textures/font_9x20.xcf differ diff --git a/game/src/ui/uiman.c b/game/src/ui/uiman.c index feb6d2e..fb9ee32 100644 --- a/game/src/ui/uiman.c +++ b/game/src/ui/uiman.c @@ -17,11 +17,13 @@ static mat4 projection; static Widget *hovered_widget = NULL; const char *lorem_ipsum = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut " - "labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " - "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit " - "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in " - "culpa qui officia deserunt mollit anim id est laborum."; + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut " + "labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " + "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit " + "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in " + "culpa qui officia deserunt mollit anim id est laborum." + " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + "!@#$%^&*()_+{}[]'\";:,<.>/?\\|`~"; void uiman_init () diff --git a/game/src/ui/widget_layout.c b/game/src/ui/widget_layout.c index 0f70b7a..0d787e9 100644 --- a/game/src/ui/widget_layout.c +++ b/game/src/ui/widget_layout.c @@ -113,93 +113,103 @@ void Widget_layout_multiline_text (Widget *self) /* Vibe coded. Dunno what the fuck it does. */ { - if (self->multiline_text.lines) - { - for (guint i = 0; i < self->multiline_text.lines->len; ++i) - { - GString *old = g_array_index (self->multiline_text.lines, GString *, i); - g_string_free (old, TRUE); - } - - g_array_free (self->multiline_text.lines, TRUE); + if (self->multiline_text.lines) + { + for (unsigned int i = 0; i < self->multiline_text.lines->len; ++i) + { + GString *old = g_array_index (self->multiline_text.lines, GString *, i); + g_string_free (old, TRUE); + } + g_array_free (self->multiline_text.lines, TRUE); + } + + GArray *lines = g_array_new (FALSE, FALSE, sizeof (GString *)); + self->multiline_text.lines = lines; + + float pad = self->style->layout_padding; + float row_h = self->multiline_text.line_height; + float char_w = row_h * (9.0 / 20.0); + float usable = self->size[0] - 2 * pad; + + const char *p = self->multiline_text.text->str; + GString *cur = g_string_new (NULL); + float cur_w = 0.0; + + while (*p) + { + const char *end = p; + + while (*end && *end != ' ' && *end != '\n') + { + end++; + } + + gsize wb = end - p; + guint wc = g_utf8_strlen(p, wb); + float w = wc * char_w; + + gboolean too_long = (w > usable); + + if (cur_w > 0 && (*end == '\n' || (!too_long && cur_w + char_w + w > usable))) + { + g_array_append_val (lines, cur); + cur = g_string_new (NULL); + cur_w = 0.0; + } + + if (too_long) + { + const char *q = p; + while (q < end) + { + gunichar ch = g_utf8_get_char (q); + const char *next = g_utf8_next_char (q); + if (cur_w + char_w > usable) + { + g_array_append_val (lines, cur); + cur = g_string_new (NULL); + cur_w = 0.0f; + } + g_string_append_unichar (cur, ch); + cur_w += char_w; + q = next; + } + } + else + { + if (cur->len > 0 && *p != '\n') + { + g_string_append_c (cur, ' '); + cur_w += char_w; + } + g_string_append_len (cur, p, wb); + cur_w += w; + } + + if (*end == '\n') + { + g_array_append_val (lines, cur); + cur = g_string_new (NULL); + cur_w = 0.0; + p = end + 1; + } + else + { + p = end; + while (*p == ' ') p++; + } } - GArray *lines = g_array_new (FALSE, FALSE, sizeof (GString *)); - self->multiline_text.lines = lines; - - float pad = self->style->layout_padding; - float row_h = self->multiline_text.line_height; - float char_w = row_h * (9.0 / 20.0); - float usable = self->size[0] - 2 * pad; - - const char *p = self->multiline_text.text->str; - GString *cur = g_string_new (NULL); - float cur_w = 0.0; - - while (*p) - { - const char *end = p; - - while (*end && *end != ' ' && *end != '\n') - { - end++; - } - - size_t wb = end - p; - size_t wc = g_utf8_strlen (p, wb); - float w = wc * char_w; - - if (*end == '\n' || (cur_w > 0 && cur_w + char_w + w > usable)) - { - g_array_append_val (lines, cur); - cur = g_string_new (NULL); - cur_w = 0.0f; - } - - if (cur->len > 0 && *p != '\n') - { - g_string_append_c (cur, ' '); - cur_w += char_w; - } - - g_string_append_len (cur, p, wb); - cur_w += w; - - if (*end == '\n') - { - g_array_append_val (lines, cur); - cur = g_string_new (NULL); - cur_w = 0.0; - p = end + 1; - } - else - { - p = end; - while (*p == ' ') - { - p++; - } - } + if (cur->len > 0) { + g_array_append_val(lines, cur); + } else { + g_string_free(cur, TRUE); } - if (cur->len > 0) - { - g_array_append_val (lines, cur); - } - else - { - g_string_free (cur, TRUE); - } + self->size[1] = pad*2 + self->multiline_text.lines->len * row_h; + self->layout_dirty = FALSE; - self->size[1] = pad * 2 + lines->len * row_h; - self->layout_dirty = FALSE; - - /* Just a hack. In case the multiline text is inside a scrollable - (which, most of the time, would be the case) we have to update - the scrollable, so it can set it's content_size properly and the - scrollbar can be the right size. */ - if (self->parent) - { - self->parent->layout_dirty = TRUE; + if (self->parent) { + self->parent->layout_dirty = TRUE; } }