Skip to content

Commit f488db9

Browse files
committed
skip UTF-8 codepoint decoding for ASCII characters
1 parent 20f0022 commit f488db9

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

CommandScreen.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,40 +49,44 @@ static int CommandScreen_scanAscii(InfoScreen* this, const char* p, size_t total
4949
static int CommandScreen_scanWide(InfoScreen* this, const char* p, size_t total, char* line) {
5050
mbstate_t state;
5151
memset(&state, 0, sizeof(state));
52-
int line_cols = 0;
53-
int line_offset = 0, line_size = 0, last_spc_cols = 0, last_spc_offset = -1;
52+
size_t bytes;
53+
int line_cols = 0, line_offset = 0, line_size = 0, width = 0;
54+
int last_spc_cols = -1, last_spc_offset = -1;
5455
for (size_t i = 0; i < total; ) {
5556
assert(line_offset >= 0 && (size_t)line_offset <= total);
56-
wchar_t wc;
57-
size_t bytes = mbrtowc(&wc, p + i, total - i, &state);
58-
int width = wcwidth(wc);
59-
if (p[i] == ' ') {
60-
last_spc_offset = line_offset;
61-
last_spc_cols = line_cols;
62-
}
63-
64-
if (bytes == (size_t)-1 || bytes == (size_t)-2) {
65-
wc = L'\xFFFD';
66-
bytes = 1;
57+
unsigned char c = (unsigned char)p[i];
58+
if (c < 0x80) { // skip mbrtowc for ASCII characters
59+
if (c == ' ') {
60+
last_spc_offset = line_offset;
61+
last_spc_cols = line_cols;
62+
}
63+
bytes = width = 1;
64+
line[line_offset] = c;
65+
} else {
66+
wchar_t wc;
67+
bytes = mbrtowc(&wc, p + i, total - i, &state);
68+
width = wcwidth(wc);
69+
if (bytes == (size_t)-1 || bytes == (size_t)-2 || width < 0) {
70+
bytes = width = 1;
71+
}
72+
memcpy(line + line_offset, p + i, bytes);
6773
}
6874

69-
memcpy(line + line_offset, p + i, bytes);
7075
i += bytes;
7176
line_offset += bytes;
7277
line_cols += width;
7378
if (line_cols < COLS) {
7479
continue;
7580
}
7681

77-
if (last_spc_offset >= 0) {
82+
if (last_spc_offset >= 0) { // wrap by last space
7883
line_size = last_spc_offset;
7984
line_cols -= last_spc_cols;
80-
last_spc_offset = -1;
81-
last_spc_cols = 0;
82-
} else if (line_cols > COLS) {
85+
last_spc_offset = last_spc_cols = -1;
86+
} else if (line_cols > COLS) { // wrap current wide char to next line
8387
line_size = line_offset - (int) bytes;
8488
line_cols = width;
85-
} else {
89+
} else { // wrap by current character
8690
line_size = line_offset;
8791
line_cols = 0;
8892
}

0 commit comments

Comments
 (0)