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 /* 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 * if the byte sequence is invalid, and return the number of bytes minus 8
* when the byte sequence encodes an invalid codepoint. */ * when it encodes an invalid codepoint. Also, in the second parameter,
int length_of_char(const char *c) * return the number of columns that the character occupies. */
int length_of_char(const char *c, int *width)
{ {
assert(c != NULL); assert(c != NULL);
@ -249,8 +250,13 @@ int length_of_char(const char *c)
/* If the codepoint is invalid... */ /* If the codepoint is invalid... */
if (!is_valid_unicode(wc)) if (!is_valid_unicode(wc))
return charlen - 8; 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; return charlen;
}
} else } else
#endif #endif
return 1; 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); bool is_word_mbchar(const char *c, bool allow_punct);
char control_rep(const signed char c); char control_rep(const signed char c);
char control_mbrep(const 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 mbwidth(const char *c);
int mb_cur_max(void); int mb_cur_max(void);
char *make_mbchar(long chr, int *chr_mb_len); 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') { while (*buf != '\0') {
int charlength; int charlength, charwidth = 1;
if (*buf == ' ') { if (*buf == ' ') {
/* Show a space as a visible character, or as a space. */ /* 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; continue;
} }
charlength = length_of_char(buf); charlength = length_of_char(buf, &charwidth);
/* If buf contains a control character, represent it. */ /* If buf contains a control character, represent it. */
if (is_cntrl_mbchar(buf)) { 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 buf contains a valid non-control character, simply copy it. */
if (charlength > 0) { if (charlength > 0) {
int width = mbwidth(buf);
for (; charlength > 0; charlength--) for (; charlength > 0; charlength--)
converted[index++] = *(buf++); converted[index++] = *(buf++);
start_col += width; start_col += charwidth;
if (width > 1) if (charwidth > 1)
seen_wide = TRUE; seen_wide = TRUE;
continue; continue;