From 446dfd085c695e350b507dfe7f2e2b0feb0794b8 Mon Sep 17 00:00:00 2001 From: lucieleblanc Date: Thu, 9 May 2024 12:23:47 -0400 Subject: [PATCH 1/4] add first-line check to incongruent direction case --- src/shape.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/shape.rs b/src/shape.rs index 6ce10146f7..de073f72b6 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -1080,13 +1080,19 @@ impl ShapeLine { word_range_width += word_width; continue; } else if wrap == Wrap::Glyph - // Make sure that the word is able to fit on it's own line, if not, fall back to Glyph wrapping. + // Make sure that the word is able to fit on its own line, if not, fall back to Glyph wrapping. || (wrap == Wrap::WordOrGlyph && word_width > line_width) + // If we're on the first line + || (wrap == Wrap::WordOrGlyph && visual_lines.len() == 0 && + // and we can't fit this word on the first line on its own + current_visual_line.w + word_width > line_width) { // Commit the current line so that the word starts on the next line. if word_range_width > 0. - && wrap == Wrap::WordOrGlyph - && word_width > line_width + && ((wrap == Wrap::WordOrGlyph && word_width > line_width) + || (wrap == Wrap::WordOrGlyph + && visual_lines.len() == 0 + && current_visual_line.w + word_width > line_width)) { add_to_visual_line( &mut current_visual_line, @@ -1212,13 +1218,15 @@ impl ShapeLine { || (wrap == Wrap::WordOrGlyph && word_width > line_width) // If we're on the first line || (wrap == Wrap::WordOrGlyph && visual_lines.len() == 0 && - // and we can't fit the rest of this word on the line - (current_visual_line.w + word_width > line_width)) + // and we can't fit the rest of this word on the current line + current_visual_line.w + word_width > line_width) { // Commit the current line so that the word starts on the next line. if word_range_width > 0. - && wrap == Wrap::WordOrGlyph - && word_width > line_width + && ((wrap == Wrap::WordOrGlyph && word_width > line_width) + || (wrap == Wrap::WordOrGlyph + && visual_lines.len() == 0 + && current_visual_line.w + word_width > line_width)) { add_to_visual_line( &mut current_visual_line, From 13df8a3da3bba31d516713ad1104e4f9cb16a2bc Mon Sep 17 00:00:00 2001 From: lucieleblanc Date: Thu, 9 May 2024 12:29:43 -0400 Subject: [PATCH 2/4] add test for bidirectional layout --- tests/wrap_stability.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/wrap_stability.rs b/tests/wrap_stability.rs index 9c6256a982..9b5bde6f14 100644 --- a/tests/wrap_stability.rs +++ b/tests/wrap_stability.rs @@ -111,6 +111,39 @@ fn wrap_extra_line() { assert_eq!(overflow_lines, 4); } +#[test] +fn wrap_bidirectional() { + let mut font_system = FontSystem::new(); + let font_size = 14.0; + let line_height = 20.0; + let buffer_width = 80.0; + + let metrics = Metrics::new(font_size, line_height); + + let mut plain_buffer = Buffer::new(&mut font_system, metrics); + + let mut buffer = plain_buffer.borrow_with(&mut font_system); + + // Add some text + buffer.set_wrap(Wrap::WordOrGlyph); + buffer.set_text( + "breakfast, إفطار, lunch (غداء) and dinner - عشاء", + Attrs::new().family(cosmic_text::Family::Name("Inter")), + Shaping::Advanced, + ); + + // Set a size for the text buffer, in pixels + buffer.set_size(buffer_width, 1000.0); + + let layout_line = buffer.line_layout(0).unwrap().first().unwrap(); + assert!( + layout_line.w <= buffer_width, + "layout line width ({}) was greater than buffer width ({})", + layout_line.w, + buffer_width + ); +} + #[allow(dead_code)] fn dbg_layout_lines(text: &str, lines: &[LayoutLine]) { for line in lines { From 7c519bace6b4c10e6bb2ff437228b5c2ab2e0be5 Mon Sep 17 00:00:00 2001 From: lucieleblanc Date: Thu, 9 May 2024 12:30:07 -0400 Subject: [PATCH 3/4] Revert "add test for bidirectional layout" This reverts commit 13df8a3da3bba31d516713ad1104e4f9cb16a2bc. --- tests/wrap_stability.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/tests/wrap_stability.rs b/tests/wrap_stability.rs index 9b5bde6f14..9c6256a982 100644 --- a/tests/wrap_stability.rs +++ b/tests/wrap_stability.rs @@ -111,39 +111,6 @@ fn wrap_extra_line() { assert_eq!(overflow_lines, 4); } -#[test] -fn wrap_bidirectional() { - let mut font_system = FontSystem::new(); - let font_size = 14.0; - let line_height = 20.0; - let buffer_width = 80.0; - - let metrics = Metrics::new(font_size, line_height); - - let mut plain_buffer = Buffer::new(&mut font_system, metrics); - - let mut buffer = plain_buffer.borrow_with(&mut font_system); - - // Add some text - buffer.set_wrap(Wrap::WordOrGlyph); - buffer.set_text( - "breakfast, إفطار, lunch (غداء) and dinner - عشاء", - Attrs::new().family(cosmic_text::Family::Name("Inter")), - Shaping::Advanced, - ); - - // Set a size for the text buffer, in pixels - buffer.set_size(buffer_width, 1000.0); - - let layout_line = buffer.line_layout(0).unwrap().first().unwrap(); - assert!( - layout_line.w <= buffer_width, - "layout line width ({}) was greater than buffer width ({})", - layout_line.w, - buffer_width - ); -} - #[allow(dead_code)] fn dbg_layout_lines(text: &str, lines: &[LayoutLine]) { for line in lines { From 704666a83fb4c53609b79a1646ff0e21824354f1 Mon Sep 17 00:00:00 2001 From: lucieleblanc Date: Mon, 13 May 2024 18:53:58 -0400 Subject: [PATCH 4/4] pull out inequalities into variables --- src/shape.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/shape.rs b/src/shape.rs index de073f72b6..fae9569378 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -1079,20 +1079,24 @@ impl ShapeLine { } word_range_width += word_width; continue; - } else if wrap == Wrap::Glyph + } + + let on_first_line = visual_lines.is_empty(); + let word_fits_on_current_line = + current_visual_line.w + word_width <= line_width; + + if wrap == Wrap::Glyph // Make sure that the word is able to fit on its own line, if not, fall back to Glyph wrapping. || (wrap == Wrap::WordOrGlyph && word_width > line_width) - // If we're on the first line - || (wrap == Wrap::WordOrGlyph && visual_lines.len() == 0 && - // and we can't fit this word on the first line on its own - current_visual_line.w + word_width > line_width) + // If we're on the first line and can't fit the word on its own + || (wrap == Wrap::WordOrGlyph && on_first_line && !word_fits_on_current_line) { // Commit the current line so that the word starts on the next line. if word_range_width > 0. && ((wrap == Wrap::WordOrGlyph && word_width > line_width) || (wrap == Wrap::WordOrGlyph - && visual_lines.len() == 0 - && current_visual_line.w + word_width > line_width)) + && on_first_line + && !word_fits_on_current_line)) { add_to_visual_line( &mut current_visual_line, @@ -1213,20 +1217,22 @@ impl ShapeLine { continue; } + let on_first_line = visual_lines.is_empty(); + let word_fits_on_current_line = + current_visual_line.w + word_width <= line_width; + if wrap == Wrap::Glyph // Make sure that the word is able to fit on it's own line, if not, fall back to Glyph wrapping. || (wrap == Wrap::WordOrGlyph && word_width > line_width) - // If we're on the first line - || (wrap == Wrap::WordOrGlyph && visual_lines.len() == 0 && - // and we can't fit the rest of this word on the current line - current_visual_line.w + word_width > line_width) + // If we're on the first line and can't fit the word on its own + || (wrap == Wrap::WordOrGlyph && on_first_line && !word_fits_on_current_line) { // Commit the current line so that the word starts on the next line. if word_range_width > 0. && ((wrap == Wrap::WordOrGlyph && word_width > line_width) || (wrap == Wrap::WordOrGlyph - && visual_lines.len() == 0 - && current_visual_line.w + word_width > line_width)) + && on_first_line + && !word_fits_on_current_line)) { add_to_visual_line( &mut current_visual_line,