Skip to content
This repository has been archived by the owner on Dec 2, 2019. It is now read-only.

Multiline text in labels #532

Open
MizantropLoL opened this issue Oct 6, 2017 · 4 comments · May be fixed by #661
Open

Multiline text in labels #532

MizantropLoL opened this issue Oct 6, 2017 · 4 comments · May be fixed by #661

Comments

@MizantropLoL
Copy link

In nk_label or nk_label_wrap, when i displaying some text with symbols '\n' or '\r', all text showing in one line with symbols '?' instead of line wraping. What i'm doing wrong?

P.S. Sorry for my English, by the way.

@uq1
Copy link

uq1 commented Dec 11, 2017

Same problem here with tooltips. Single line tooltips are not of much use for a game.

@alekseyt
Copy link

alekseyt commented Nov 22, 2019

Sorry for bumping old issue, i stumbled across it when looking for duplicate issues. I also need to display multiline text. Here is my take on this: i saw #661 but i'm not sure if new API functions are really needed to display such text. IMO it could be separated into two problems:

  1. nk_label() and nk_label_wrap() don't handle \r or \n
  2. \r and \n are displayed as ? on screen

So below is a patch that solves both problems, it's like 10 lines of code or so. Sadly i had to change indentation of some lines too, but it's basically 3 ifs. I'm aware that nuklear now has dedicated files for different parts of library, but this is patch is for amalgamated nuklear.h, it's easier to present it this way. It should apply cleanly to adc52d7.

diff --git a/nuklear.h b/nuklear.h
index e847d5e..f24da9e 100644
--- a/nuklear.h
+++ b/nuklear.h
@@ -3720,6 +3720,14 @@ NK_API struct nk_rect nk_rectv(const float *xywh);
 NK_API struct nk_rect nk_rectiv(const int *xywh);
 NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
 NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
+/* =============================================================================
+ *
+ *                                  UTIL
+ *
+ * ============================================================================= */
+NK_API int nk_text_clamp(const struct nk_user_font *font, const char *text,
+    int text_len, float space, int *glyphs, float *text_width,
+    nk_rune *sep_list, int sep_count);
 /* =============================================================================
  *
  *                                  STRING
@@ -5822,7 +5830,7 @@ NK_LIB void nk_zero(void *ptr, nk_size size);
 NK_LIB char *nk_itoa(char *s, long n);
 NK_LIB int nk_string_float_limit(char *string, int prec);
 NK_LIB char *nk_dtoa(char *s, double n);
-NK_LIB int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
+NK_API int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
 NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, int byte_len, float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op);
 #ifdef NK_INCLUDE_STANDARD_VARARGS
 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
@@ -7328,7 +7336,7 @@ nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
     return buf;
 }
 #endif
-NK_LIB int
+NK_API int
 nk_text_clamp(const struct nk_user_font *font, const char *text,
     int text_len, float space, int *glyphs, float *text_width,
     nk_rune *sep_list, int sep_count)
@@ -7350,6 +7358,12 @@ nk_text_clamp(const struct nk_user_font *font, const char *text,
     glyph_len = nk_utf_decode(text, &unicode, text_len);
     while (glyph_len && (width < space) && (len < text_len)) {
         len += glyph_len;
+        if (unicode == '\n' || unicode == '\r') {
+            sep_width = last_width = width;
+            sep_g = g+1;
+            sep_len = len;
+            break;
+        }
         s = font->width(font->userdata, font->height, text, len);
         for (i = 0; i < sep_count; ++i) {
             if (unicode != sep_list[i]) continue;
@@ -10366,23 +10380,25 @@ nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font
         float gx, gy, gh, gw;
         float char_width = 0;
         if (unicode == NK_UTF_INVALID) break;
-
-        /* query currently drawn glyph information */
-        next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
-        font->query(font->userdata, font_height, &g, unicode,
-                    (next == NK_UTF_INVALID) ? '\0' : next);
-
-        /* calculate and draw glyph drawing rectangle and image */
-        gx = x + g.offset.x;
-        gy = rect.y + g.offset.y;
-        gw = g.width; gh = g.height;
-        char_width = g.xadvance;
-        nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
-            g.uv[0], g.uv[1], fg);
+        if (unicode != '\n' && unicode != '\r') {
+            /* query currently drawn glyph information */
+            next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
+            font->query(font->userdata, font_height, &g, unicode,
+                        (next == NK_UTF_INVALID) ? '\0' : next);
+
+            /* calculate and draw glyph drawing rectangle and image */
+            gx = x + g.offset.x;
+            gy = rect.y + g.offset.y;
+            gw = g.width; gh = g.height;
+            char_width = g.xadvance;
+            nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
+                g.uv[0], g.uv[1], fg);
+
+            x += char_width;
+        }
 
         /* offset next glyph */
         text_len += glyph_len;
-        x += char_width;
         glyph_len = next_glyph_len;
         unicode = next;
     }
@@ -13026,10 +13042,11 @@ nk_font_text_width(nk_handle handle, float height, const char *text, int len)
     while (text_len <= (int)len && glyph_len) {
         const struct nk_font_glyph *g;
         if (unicode == NK_UTF_INVALID) break;
-
-        /* query currently drawn glyph information */
-        g = nk_font_find_glyph(font, unicode);
-        text_width += g->xadvance * scale;
+        if (unicode != '\n' && unicode != '\r') {
+            /* query currently drawn glyph information */
+            g = nk_font_find_glyph(font, unicode);
+            text_width += g->xadvance * scale;
+        }
 
         /* offset next glyph */
         glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);

So basically with this patch \r and \n are not displayed on screen (skipped) and nk_text_clamp() will clamp on \r and \n as if width limit was reached. It also would be nice to make nk_text_clamp() into NK_API instead of NK_LIB so it's possible to tell beforehand how many lines text would take, but it's not a big deal, it can be excluded from patch.

How does that look, is that something that could potentially be merged?

@vurtun @dumblob

@dumblob
Copy link
Contributor

dumblob commented Nov 22, 2019

Didn't have time to think much of this, but on the first sight it seems the patch does wrap the text twice in case it CRLF and not just either of CR or LF.

The API seems clear to me, but I'd like to hear what the thoughts of @AntiBlueQuirk would be about this patch instead of
#661 .

@alekseyt
Copy link

alekseyt commented Nov 22, 2019

No, it doesn't handle CRLF, neither other newline characters line NEL. This is a bare minimum to fit into github comment. Other newline characters are just extension of [ CR, LF ] set, CR+LF is one read-ahead with proper checks or so i think.

By the way, line terminators could be passed to nk_text_clamp() similarly to word separators, but probably it's better to pass a function instead of array. If we all could agree on general approach, then i think this patch could be potentially extended.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants