commit e33a0b6dbec351c188cf51934dd63250aab654df
parent 0894587305387fec8ab78199a69e3d7abcc21e2f
Author: Benno Schulenberg <bensberg@justemail.net>
Date: Mon, 6 Jun 2016 13:20:04 +0200
screen: avoid converting each character twice from multibyte to wide
Diffstat:
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/chars.c b/src/chars.c
@@ -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;
diff --git a/src/proto.h b/src/proto.h
@@ -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);
diff --git a/src/winio.c b/src/winio.c
@@ -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;