diff options
author | Oriol Brufau <obrufau@igalia.com> | 2024-04-15 14:02:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-15 12:02:09 +0000 |
commit | 1898394cb363114e67ba2ea1ae8cff2802062c8f (patch) | |
tree | b7f00616ff7642e8cfcb97551663ae91714f72dc /components | |
parent | 5083dc7d170b1c1b9c27a278400ec2e7b5ae17cd (diff) | |
download | servo-1898394cb363114e67ba2ea1ae8cff2802062c8f.tar.gz servo-1898394cb363114e67ba2ea1ae8cff2802062c8f.zip |
Keep 1st collapsible space after a preserved one (#32037)
The logic was to remove any collapsible white space preceded by other
white space. However, this should only happen if the preceding space
is also collapsible.
Also fixing the logic in ContentSizesComputation, which was wrong
but previously it didn't matter.
Diffstat (limited to 'components')
-rw-r--r-- | components/layout_2020/flow/inline.rs | 13 | ||||
-rw-r--r-- | components/layout_2020/flow/text_run.rs | 21 |
2 files changed, 19 insertions, 15 deletions
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 2bd7c5697f3..247ae3542c4 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -2306,7 +2306,8 @@ struct ContentSizesComputation<'a> { current_line: ContentSizes, /// Size for whitepsace pending to be added to this line. pending_whitespace: Au, - /// Whether or not this IFC has seen any content, excluding collapsed whitespace. + /// Whether or not the current line has seen any content (excluding collapsed whitespace), + /// when sizing under a max-content constraint. had_content_yet: bool, /// Stack of ending padding, margin, and border to add to the length /// when an inline box finishes. @@ -2366,7 +2367,6 @@ impl<'a> ContentSizesComputation<'a> { // If this run is a forced line break, we *must* break the line // and start measuring from the inline origin once more. if text_run.glyph_run_is_preserved_newline(run) { - self.had_content_yet = true; self.forced_line_break(); self.current_line = ContentSizes::zero(); continue; @@ -2375,12 +2375,12 @@ impl<'a> ContentSizesComputation<'a> { let white_space = text_run.parent_style.get_inherited_text().white_space; if !white_space.preserve_spaces() { - // Discard any leading whitespace in the IFC. This will always be trimmed. + // TODO: need to handle !white_space.allow_wrap(). + self.line_break_opportunity(); + // Discard any leading whitespace in the line. This will always be trimmed. if self.had_content_yet { // Wait to take into account other whitespace until we see more content. - // Whitespace at the end of the IFC will always be trimmed. - // TODO: need to handle !white_space.allow_wrap(). - self.line_break_opportunity(); + // Whitespace at the end of the line will always be trimmed. self.pending_whitespace += advance; } continue; @@ -2433,6 +2433,7 @@ impl<'a> ContentSizesComputation<'a> { self.paragraph.max_content = std::cmp::max(self.paragraph.max_content, self.current_line.max_content); self.current_line.max_content = Au::zero(); + self.had_content_yet = false; } fn commit_pending_whitespace(&mut self) { diff --git a/components/layout_2020/flow/text_run.rs b/components/layout_2020/flow/text_run.rs index 1f237d6a8a4..bccedebea5d 100644 --- a/components/layout_2020/flow/text_run.rs +++ b/components/layout_2020/flow/text_run.rs @@ -211,13 +211,13 @@ impl TextRun { font_context: &mut FontContext<FontCacheThread>, linebreaker: &mut Option<LineBreakLeafIter>, font_cache: &mut Vec<FontKeyAndMetrics>, - last_inline_box_ended_with_white_space: &mut bool, + last_inline_box_ended_with_collapsible_white_space: &mut bool, on_word_boundary: &mut bool, ) { let segment_results = self.segment_text( font_context, font_cache, - last_inline_box_ended_with_white_space, + last_inline_box_ended_with_collapsible_white_space, on_word_boundary, ); let inherited_text_style = self.parent_style.get_inherited_text().clone(); @@ -282,7 +282,7 @@ impl TextRun { &mut self, font_context: &mut FontContext<FontCacheThread>, font_cache: &mut Vec<FontKeyAndMetrics>, - last_inline_box_ended_with_white_space: &mut bool, + last_inline_box_ended_with_collapsible_white_space: &mut bool, on_word_boundary: &mut bool, ) -> Vec<(TextRunSegment, FontRef)> { let font_group = font_context.font_group(self.parent_style.clone_font()); @@ -291,10 +291,11 @@ impl TextRun { // TODO: Eventually the text should come directly from the Cow strings of the DOM nodes. let text = std::mem::take(&mut self.text); + let white_space = self.parent_style.clone_white_space(); let collapsed = WhitespaceCollapse::new( text.as_str().chars(), - self.parent_style.clone_white_space(), - *last_inline_box_ended_with_white_space, + white_space, + *last_inline_box_ended_with_collapsible_white_space, ); let text_transform = self.parent_style.clone_text_transform(); @@ -304,8 +305,9 @@ impl TextRun { // `TextTransformation` doesn't support capitalization, so we must capitalize the whole // string at once and make a copy. Here `on_word_boundary` indicates whether or not the // inline formatting context as a whole is on a word boundary. This is different from - // `last_inline_box_ended_with_white_space` because the word boundaries are between - // atomic inlines and at the start of the IFC. + // `last_inline_box_ended_with_collapsible_white_space` because the word boundaries are + // between atomic inlines and at the start of the IFC, and because preserved spaces + // are a word boundary. let collapsed_string: String = collapsed.collect(); collected_text = capitalize_string(&collapsed_string, *on_word_boundary); Box::new(collected_text.chars()) @@ -323,8 +325,9 @@ impl TextRun { let current_byte_index = next_byte_index; next_byte_index += character.len_utf8(); - *last_inline_box_ended_with_white_space = character.is_whitespace(); - *on_word_boundary = *last_inline_box_ended_with_white_space; + *on_word_boundary = character.is_whitespace(); + *last_inline_box_ended_with_collapsible_white_space = + *on_word_boundary && !white_space.preserve_spaces(); let prevents_soft_wrap_opportunity = char_prevents_soft_wrap_opportunity_when_before_or_after_atomic(character); |