screen: avoid converting each character twice from multibyte to wide
parent
0894587305
commit
e33a0b6dbe
12
src/chars.c
12
src/chars.c
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
10
src/winio.c
10
src/winio.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue