From c630a8de894b28bf1774f798b1b1fe90a759ee42 Mon Sep 17 00:00:00 2001 From: Juan Campa Date: Sun, 21 Apr 2024 04:58:40 -0400 Subject: [PATCH] Fix incorrect line breaks (#4377) While breaking a paragraph, it was possible to lose line break candidates that could've been used on the next line, causing egui to unnecessarily overrun `wrap.max_width`. This PR fixes it so that we don't forget about those candidates. Before: Note that the window can't resize to the requested width because the text is not wrapping. https://github.com/emilk/egui/assets/1410520/6430a334-2995-4b40-bc34-8f01923f9f95 After: https://github.com/emilk/egui/assets/1410520/225fa4cd-cbbb-4a7e-9580-7f1814c05ee7 --------- Co-authored-by: Emil Ernerfeldt --- crates/epaint/src/text/text_layout.rs | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/crates/epaint/src/text/text_layout.rs b/crates/epaint/src/text/text_layout.rs index 322026da3c5..c9956aac197 100644 --- a/crates/epaint/src/text/text_layout.rs +++ b/crates/epaint/src/text/text_layout.rs @@ -296,7 +296,7 @@ fn line_break(paragraph: &Paragraph, job: &LayoutJob, out_rows: &mut Vec, e // Start a new row: row_start_idx = last_kept_index + 1; row_start_x = paragraph.glyphs[row_start_idx].pos.x; - row_break_candidates = Default::default(); + row_break_candidates.forget_before_idx(row_start_idx); } else { // Found no place to break, so we have to overrun wrap_width. } @@ -943,6 +943,35 @@ impl RowBreakCandidates { .or(self.any) } } + + fn forget_before_idx(&mut self, index: usize) { + let Self { + space, + cjk, + pre_cjk, + dash, + punctuation, + any, + } = self; + if space.map_or(false, |s| s < index) { + *space = None; + } + if cjk.map_or(false, |s| s < index) { + *cjk = None; + } + if pre_cjk.map_or(false, |s| s < index) { + *pre_cjk = None; + } + if dash.map_or(false, |s| s < index) { + *dash = None; + } + if punctuation.map_or(false, |s| s < index) { + *punctuation = None; + } + if any.map_or(false, |s| s < index) { + *any = None; + } + } } #[inline]