Fix incorrect handling of VS16 when it causes char to wrap to next line and is part of a draw command with more characters following it

Needed to initialize full text loop state rather than just segmentation
state on wrap. Fixes #8848
This commit is contained in:
Kovid Goyal 2025-07-26 09:25:01 +05:30
parent 0f67ff37df
commit f61b15b284
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 12 additions and 5 deletions

View file

@ -122,6 +122,8 @@ Detailed list of changes
- Watchers: A new event for global watchers corresponding to the tab bar being changed (:disc:`8842`)
- Fix a regression in 0.40.0 that broke handing of the VS16 variation selector when it caused a character to reflow to the next line (:iss:`8848`)
0.42.2 [2025-07-16]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -944,7 +944,8 @@ move_cursor_past_multicell(Screen *self, index_type required_width) {
}
static void
move_widened_char_past_multiline_chars(Screen *self, CPUCell* cpu_cell, GPUCell *gpu_cell, index_type xpos, index_type ypos) {
move_widened_char_past_multiline_chars(Screen *self, text_loop_state *s, CPUCell* cpu_cell, GPUCell *gpu_cell, index_type xpos, index_type ypos) {
index_type before = self->cursor->y;
self->cursor->x = xpos; self->cursor->y = ypos;
if (move_cursor_past_multicell(self, 2)) {
CPUCell *cp; GPUCell *gp;
@ -957,6 +958,8 @@ move_widened_char_past_multiline_chars(Screen *self, CPUCell* cpu_cell, GPUCell
self->cursor->x++;
}
*cpu_cell = (CPUCell){0}; *gpu_cell = (GPUCell){0};
if (self->cursor->y == before) init_segmentation_state(self, s);
else init_text_loop_line(self, s);
}
static bool
@ -984,8 +987,7 @@ draw_combining_char(Screen *self, text_loop_state *s, char_type ch) {
CPUCell *second = cp + xpos + 1;
if (second->is_multicell) {
if (second->y) {
move_widened_char_past_multiline_chars(self, cpu_cell, gpu_cell, xpos, s->prev.y);
init_segmentation_state(self, s);
move_widened_char_past_multiline_chars(self, s, cpu_cell, gpu_cell, xpos, s->prev.y);
return;
}
nuke_multicell_char_at(self, xpos + 1, s->prev.y, false);
@ -994,8 +996,7 @@ draw_combining_char(Screen *self, text_loop_state *s, char_type ch) {
self->cursor->x++;
*second = *cpu_cell; second->x = 1;
} else {
move_widened_char_past_multiline_chars(self, cpu_cell, gpu_cell, xpos, s->prev.y);
init_segmentation_state(self, s);
move_widened_char_past_multiline_chars(self, s, cpu_cell, gpu_cell, xpos, s->prev.y);
}
}
} else if (ch == VS15) {

View file

@ -732,6 +732,10 @@ class TestScreen(BaseTest):
self.ae(s.text_for_selection(), ('a\u00adb',))
def test_variation_selectors(self):
s = self.create_screen(cols=3)
q = '*\ufe0f'
s.draw(q*(s.columns+1))
self.ae(str(s.line(0)), q*(s.columns//2))
s = self.create_screen(cols=8)
def widths(text, *widths):
s.reset()