diff --git a/parley/src/resolve/tree.rs b/parley/src/resolve/tree.rs index 023ea9e72..9acd9b8b3 100644 --- a/parley/src/resolve/tree.rs +++ b/parley/src/resolve/tree.rs @@ -167,7 +167,6 @@ impl TreeStyleBuilder { style_id: None, }); self.current_span = self.tree.len() - 1; - self.is_span_first = true; } pub(crate) fn push_style_modification_span( @@ -182,7 +181,7 @@ impl TreeStyleBuilder { } pub(crate) fn pop_style_span(&mut self) { - self.push_uncommitted_text(true); + self.push_uncommitted_text(false); self.current_span = self.tree[self.current_span] .parent diff --git a/parley/src/tests/test_builders.rs b/parley/src/tests/test_builders.rs index f098cfe17..9a403c719 100644 --- a/parley/src/tests/test_builders.rs +++ b/parley/src/tests/test_builders.rs @@ -13,7 +13,7 @@ use super::utils::{ColorBrush, asserts::assert_eq_layout_data}; use crate::{ BaseDirection, FontContext, FontFamily, FontFeatures, FontVariations, Layout, LayoutContext, LineHeight, OverflowWrap, RangedBuilder, StyleProperty, StyleRunBuilder, TextStyle, - TextWrapMode, TreeBuilder, WordBreak, + TextWrapMode, TreeBuilder, WhiteSpaceCollapse, WordBreak, }; // TODO: `FONT_FAMILY_LIST`, `load_fonts`, and `create_font_context` are @@ -649,6 +649,30 @@ fn builders_crlf_counts_as_single_line_break() { ); } +/// Whitespace collapsing must not remove whitespace at style span boundaries: +/// a span's leading/trailing spaces are only trimmed when they are at the start +/// of the text or follow existing whitespace. +#[test] +fn tree_builder_collapse_preserves_whitespace_at_span_boundaries() { + let mut fcx = create_font_context(); + let mut lcx: LayoutContext = LayoutContext::new(); + let root_style = create_root_style(); + + let mut tb = lcx.tree_builder(&mut fcx, 1.0, false, &root_style); + tb.set_white_space_mode(WhiteSpaceCollapse::Collapse); + tb.push_text(" Singer-songwriter"); + tb.push_style_modification_span(&[StyleProperty::FontSize(40.)]); + tb.push_text("\u{a0} · "); + tb.pop_style_span(); + tb.push_text("actress"); + let (_, text) = tb.build(); + + assert_eq!( + text, "Singer-songwriter\u{a0} · actress", + "spaces inside a style span must survive whitespace collapsing" + ); +} + /// A CRLF whose `\r` and `\n` land in different shaped runs (because a style /// change starts at the `\n`) must still coalesce into a single hard break. #[test]