Handle wide character display based on wcwidth implementation (UTF-16 ready).

This commit is contained in:
Renaud 2019-11-06 11:24:18 +08:00
parent d18cfd2925
commit b0362969a3
4 changed files with 20 additions and 10 deletions

View File

@ -340,7 +340,7 @@ static unsigned int utf8_disp_len( const char *s) {
unicode_t c ; unicode_t c ;
s += utf8_to_unicode( s, 0, 4, &c) ; s += utf8_to_unicode( s, 0, 4, &c) ;
len += 1 ; /* single width unicode for now */ len += utf8_width( c) ;
} }
return len ; return len ;

View File

@ -232,7 +232,7 @@ static int vtputs( const char *s) {
s += utf8_to_unicode( s, 0, 4, &c) ; s += utf8_to_unicode( s, 0, 4, &c) ;
vtputc( c) ; vtputc( c) ;
n += 1 ; /* Assume non wide char unicode */ n += utf8_width( c) ;
} }
return n ; return n ;
@ -569,10 +569,8 @@ void updpos(void)
curcol += 2 ; /* displayed as ^c */ curcol += 2 ; /* displayed as ^c */
else if( c >= 0x80 && c <= 0xA0) else if( c >= 0x80 && c <= 0xA0)
curcol += 3 ; /* displayed as \xx */ curcol += 3 ; /* displayed as \xx */
else if( c >= 0x3000 && c <= 0x3FFF)
curcol += 2 ; /* double width unicode character */
else else
curcol += 1 ; curcol += utf8_width( c) ;
} }
/* if extended, flag so and update the virtual line image */ /* if extended, flag so and update the virtual line image */
@ -585,7 +583,7 @@ void updpos(void)
/* /*
* upddex: * upddex:
* de-extend any line that derserves it * de-extend any line that deserves it
*/ */
void upddex(void) 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 /* scan through the line and dump it to the screen and
the virtual screen array */ the virtual screen array */
cp3 = &vp1->v_text[term.t_ncol]; while( ttcol < term.t_ncol) {
while (cp1 < cp3) { /* TODO: handle double width unicode char at last screen col */
TTputc(*cp1); TTputc(*cp1);
++ttcol; ttcol += utf8_width( *cp1) ;
*cp2++ = *cp1++; *cp2++ = *cp1++;
} }
@ -1048,7 +1046,7 @@ static int updateline(int row, struct video *vp1, struct video *vp2)
while (cp1 != cp5) { /* Ordinary. */ while (cp1 != cp5) { /* Ordinary. */
TTputc(*cp1); TTputc(*cp1);
++ttcol; ttcol += utf8_width( *cp1) ;
*cp2++ = *cp1++; *cp2++ = *cp1++;
} }

11
utf8.c
View File

@ -1,8 +1,19 @@
/* utf8.c -- implements utf8.h, converts between unicode and UTF-8 */ /* utf8.c -- implements utf8.h, converts between unicode and UTF-8 */
#define _XOPEN_SOURCE /* wcwidth in wchar.h */
#include "utf8.h" #include "utf8.h"
#include <assert.h> #include <assert.h>
#include <wchar.h>
/*
* 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() * utf8_to_unicode()

1
utf8.h
View File

@ -3,6 +3,7 @@
typedef unsigned int unicode_t ; typedef unsigned int unicode_t ;
unsigned utf8_width( unicode_t c) ;
unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len, unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
unicode_t *res) ; unicode_t *res) ;
unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ; unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ;