[PATCH] ui/ncurses: Display multibyte strings correctly in textscreens

Samuel Mendoza-Jonas sam at mendozajonas.com
Tue Oct 10 15:59:53 AEDT 2017


In nc-textscreen each line of text is capped at a certain length to
avoid running off the side of the viewable screen. However it appears
the ncurses function mvwaddnstr() counts by byte instead of actual
character, causing strings which contain multibyte characters to be cut
short.

To avoid this check the displayed length of each string against the
screen width, and if under instruct mvwaddnstr() to print the whole
string.

Signed-off-by: Samuel Mendoza-Jonas <sam at mendozajonas.com>
---
 ui/ncurses/nc-textscreen.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/ui/ncurses/nc-textscreen.c b/ui/ncurses/nc-textscreen.c
index a460188..0be2016 100644
--- a/ui/ncurses/nc-textscreen.c
+++ b/ui/ncurses/nc-textscreen.c
@@ -41,15 +41,17 @@ struct text_screen *text_screen_from_scr(struct nc_scr *scr)
 
 void text_screen_draw(struct text_screen *screen)
 {
-	int max_y, max_x, i;
+	int max_y, max_x, i, len;
 
 	max_y = getmaxy(screen->scr.sub_ncw);
 	max_x = getmaxx(screen->scr.sub_ncw) - 1;
 
 	max_y = min(max_y, screen->scroll_y + screen->n_lines);
 
-	for (i = screen->scroll_y; i < max_y; i++)
-		mvwaddnstr(screen->scr.sub_ncw, i, 1, screen->lines[i], max_x);
+	for (i = screen->scroll_y; i < max_y; i++) {
+		len = strncols(screen->lines[i]) > max_x ? max_x : -1;
+		mvwaddnstr(screen->scr.sub_ncw, i, 1, screen->lines[i], len);
+	}
 
 	wrefresh(screen->scr.sub_ncw);
 }
@@ -58,7 +60,7 @@ static void text_screen_scroll(struct text_screen *screen, int key)
 {
 	int win_lines = getmaxy(screen->scr.sub_ncw);
 	int win_cols = getmaxx(screen->scr.sub_ncw) - 1;
-	int delta;
+	int delta, len, i;
 
 	if (key == KEY_UP)
 		delta = -1;
@@ -75,13 +77,16 @@ static void text_screen_scroll(struct text_screen *screen, int key)
 	screen->scroll_y += delta;
 	wscrl(screen->scr.sub_ncw, delta);
 
+
 	if (delta > 0) {
+		i = screen->scroll_y + win_lines - 1;
+		len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
 		mvwaddnstr(screen->scr.sub_ncw, win_lines - 1, 1,
-				screen->lines[screen->scroll_y+win_lines-1],
-				win_cols);
+				screen->lines[i], len);
 	} else if (delta < 0) {
-		mvwaddnstr(screen->scr.sub_ncw, 0, 1,
-				screen->lines[screen->scroll_y], win_cols);
+		i = screen->scroll_y;
+		len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
+		mvwaddnstr(screen->scr.sub_ncw, 0, 1, screen->lines[i], len);
 	}
 
 	wrefresh(screen->scr.sub_ncw);
-- 
2.14.2



More information about the Petitboot mailing list