diff --git a/kitty/simd-string.c b/kitty/simd-string.c index 182a0517e..8e4c3c0d5 100644 --- a/kitty/simd-string.c +++ b/kitty/simd-string.c @@ -123,3 +123,18 @@ uint8_t* find_either_of_two_bytes(uint8_t *haystack, const size_t sz, const uint8_t a, const uint8_t b) { return find_either_of_two_bytes_simd(haystack, sz, a, b); } + +static const uint8_t* +find_start_of_two_ranges_simple(const uint8_t *haystack, const size_t sz, const uint8_t a1, const uint8_t a2, const uint8_t a3, const uint8_t a4) { + ByteLoader it; byte_loader_init(&it, haystack, sz); + while (it.num_left) { + const uint8_t ch = byte_loader_next(&it); + if ((a1 <= ch && ch <= a2) || (a3 <= ch && ch <= a4)) return haystack + sz - it.num_left - 1; + } + return NULL; +} + +uint8_t* +find_start_of_two_ranges(uint8_t *haystack, const size_t sz, const uint8_t a1, const uint8_t a2, const uint8_t a3, const uint8_t a4) { + return (uint8_t*)find_start_of_two_ranges_simple(haystack, sz, a1, a2, a3, a4); +} diff --git a/kitty/simd-string.h b/kitty/simd-string.h index 74f373f51..9da140137 100644 --- a/kitty/simd-string.h +++ b/kitty/simd-string.h @@ -25,3 +25,9 @@ uint8_t byte_loader_next(ByteLoader *self); // be readable. Returns pointer to first position in haystack that contains // either of the two chars or NULL if not found. uint8_t* find_either_of_two_bytes(uint8_t *haystack, const size_t sz, const uint8_t a, const uint8_t b); + +// Requires haystack[sz] to be writable and 7 bytes to the left of haystack to +// be readable. Returns pointer to first position in haystack that contains +// a char that is in [a1, a2] or [a2, a3] +uint8_t* +find_start_of_two_ranges(uint8_t *haystack, const size_t sz, const uint8_t a1, const uint8_t a2, const uint8_t a3, const uint8_t a4); diff --git a/kitty/vt-parser.c b/kitty/vt-parser.c index 4492c70f9..af1c5abcf 100644 --- a/kitty/vt-parser.c +++ b/kitty/vt-parser.c @@ -272,14 +272,26 @@ dispatch_normal_mode_byte(PS *self, uint8_t ch) { } static void -consume_normal(PS *self) { - const unsigned sz = self->read.sz - self->read.pos; - ByteLoader b; byte_loader_init(&b, self->buf + self->read.pos, sz); - while (b.num_left && self->vte_state == VTE_NORMAL) { - uint8_t ch = byte_loader_next(&b); - dispatch_normal_mode_byte(self, ch); +dispatch_printable_ascii(PS *self, const size_t sz) { + for (const size_t limit = self->read.pos + sz; self->read.pos < limit; self->read.pos++) { + REPORT_DRAW(self->buf[self->read.pos]); + screen_draw(self->screen, self->buf[self->read.pos], true); } - self->read.pos += sz - b.num_left; +} + +static void +consume_normal(PS *self) { + do { + if (self->utf8.state == UTF8_ACCEPT) { + size_t sz = self->read.sz - self->read.pos; + uint8_t *p = find_start_of_two_ranges(self->buf + self->read.pos, sz, 0, 31, 0x7f, 0xff); + if (p != NULL) sz = p - (self->buf + self->read.pos); + if (sz) dispatch_printable_ascii(self, sz); + else dispatch_normal_mode_byte(self, self->buf[self->read.pos++]); + } else { + dispatch_normal_mode_byte(self, self->buf[self->read.pos++]); + } + } while (self->read.pos < self->read.sz && self->vte_state == VTE_NORMAL); } // }}}