From eac7fc04e7ce07f6b1a6a0d19af86ae7f74ebc5e Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Tue, 10 Oct 2017 15:36:27 +1100 Subject: ui/ncurses: Display multibyte strings correctly in textscreens 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 --- ui/ncurses/nc-textscreen.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'ui/ncurses/nc-textscreen.c') 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); -- cgit v1.2.1