From b0362969a3e172bf14396851369b0f7cc4e9c1bd Mon Sep 17 00:00:00 2001 From: Renaud Fivet Date: Wed, 6 Nov 2019 11:24:18 +0800 Subject: [PATCH] Handle wide character display based on wcwidth implementation (UTF-16 ready). --- buffer.c | 2 +- display.c | 16 +++++++--------- utf8.c | 11 +++++++++++ utf8.h | 1 + 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/buffer.c b/buffer.c index a69449e..0fb7dbb 100644 --- a/buffer.c +++ b/buffer.c @@ -340,7 +340,7 @@ static unsigned int utf8_disp_len( const char *s) { unicode_t c ; s += utf8_to_unicode( s, 0, 4, &c) ; - len += 1 ; /* single width unicode for now */ + len += utf8_width( c) ; } return len ; diff --git a/display.c b/display.c index 9e8f6bd..2beac7f 100644 --- a/display.c +++ b/display.c @@ -232,7 +232,7 @@ static int vtputs( const char *s) { s += utf8_to_unicode( s, 0, 4, &c) ; vtputc( c) ; - n += 1 ; /* Assume non wide char unicode */ + n += utf8_width( c) ; } return n ; @@ -569,10 +569,8 @@ void updpos(void) curcol += 2 ; /* displayed as ^c */ else if( c >= 0x80 && c <= 0xA0) curcol += 3 ; /* displayed as \xx */ - else if( c >= 0x3000 && c <= 0x3FFF) - curcol += 2 ; /* double width unicode character */ else - curcol += 1 ; + curcol += utf8_width( c) ; } /* if extended, flag so and update the virtual line image */ @@ -585,7 +583,7 @@ void updpos(void) /* * upddex: - * de-extend any line that derserves it + * de-extend any line that deserves it */ void upddex(void) { @@ -977,10 +975,10 @@ static int updateline(int row, struct video *vp1, struct video *vp2) /* scan through the line and dump it to the screen and the virtual screen array */ - cp3 = &vp1->v_text[term.t_ncol]; - while (cp1 < cp3) { + while( ttcol < term.t_ncol) { + /* TODO: handle double width unicode char at last screen col */ TTputc(*cp1); - ++ttcol; + ttcol += utf8_width( *cp1) ; *cp2++ = *cp1++; } @@ -1048,7 +1046,7 @@ static int updateline(int row, struct video *vp1, struct video *vp2) while (cp1 != cp5) { /* Ordinary. */ TTputc(*cp1); - ++ttcol; + ttcol += utf8_width( *cp1) ; *cp2++ = *cp1++; } diff --git a/utf8.c b/utf8.c index b35c509..181f6ac 100644 --- a/utf8.c +++ b/utf8.c @@ -1,8 +1,19 @@ /* utf8.c -- implements utf8.h, converts between unicode and UTF-8 */ +#define _XOPEN_SOURCE /* wcwidth in wchar.h */ + #include "utf8.h" #include +#include + +/* + * Display width of UTF-8 character + */ +unsigned utf8_width( unicode_t c) { + assert( sizeof( wchar_t) == 2) ; /* wcwidth only handle UTF-16 */ + return (c < 0x10000) ? (unsigned) wcwidth( (wchar_t) c) : 2 ; +} /* * utf8_to_unicode() diff --git a/utf8.h b/utf8.h index bfc6b16..ae61faf 100644 --- a/utf8.h +++ b/utf8.h @@ -3,6 +3,7 @@ typedef unsigned int unicode_t ; +unsigned utf8_width( unicode_t c) ; unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len, unicode_t *res) ; unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ;