screen: avoid converting each character twice from multibyte to wide

master
Benno Schulenberg 2016-06-06 13:20:04 +02:00
parent 0894587305
commit e33a0b6dbe
3 changed files with 14 additions and 10 deletions

View File

@ -230,8 +230,9 @@ char control_mbrep(const char *c)
/* Assess how many bytes the given (multibyte) character occupies. Return -1
* if the byte sequence is invalid, and return the number of bytes minus 8
* when the byte sequence encodes an invalid codepoint. */
int length_of_char(const char *c)
* when it encodes an invalid codepoint. Also, in the second parameter,
* return the number of columns that the character occupies. */
int length_of_char(const char *c, int *width)
{
assert(c != NULL);
@ -249,8 +250,13 @@ int length_of_char(const char *c)
/* If the codepoint is invalid... */
if (!is_valid_unicode(wc))
return charlen - 8;
else
else {
*width = wcwidth(wc);
/* If the codepoint is unassigned, assume a width of one. */
if (*width < 0)
*width = 1;
return charlen;
}
} else
#endif
return 1;

View File

@ -188,7 +188,7 @@ bool is_punct_mbchar(const char *c);
bool is_word_mbchar(const char *c, bool allow_punct);
char control_rep(const signed char c);
char control_mbrep(const char *c);
int length_of_char(const char *c);
int length_of_char(const char *c, int *width);
int mbwidth(const char *c);
int mb_cur_max(void);
char *make_mbchar(long chr, int *chr_mb_len);

View File

@ -1780,7 +1780,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
}
while (*buf != '\0') {
int charlength;
int charlength, charwidth = 1;
if (*buf == ' ') {
/* Show a space as a visible character, or as a space. */
@ -1817,7 +1817,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
continue;
}
charlength = length_of_char(buf);
charlength = length_of_char(buf, &charwidth);
/* If buf contains a control character, represent it. */
if (is_cntrl_mbchar(buf)) {
@ -1830,13 +1830,11 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
/* If buf contains a valid non-control character, simply copy it. */
if (charlength > 0) {
int width = mbwidth(buf);
for (; charlength > 0; charlength--)
converted[index++] = *(buf++);
start_col += width;
if (width > 1)
start_col += charwidth;
if (charwidth > 1)
seen_wide = TRUE;
continue;