diff mbox series

ui/ncurses: Display multibyte strings correctly in textscreens

Message ID 20171010045953.20368-1-sam@mendozajonas.com
State Accepted
Headers show
Series ui/ncurses: Display multibyte strings correctly in textscreens | expand

Commit Message

Sam Mendoza-Jonas Oct. 10, 2017, 4:59 a.m. UTC
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@mendozajonas.com>
---
 ui/ncurses/nc-textscreen.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
diff mbox series

Patch

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);