diff options
author | Martin Robinson <mrobinson@igalia.com> | 2023-12-01 10:26:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-01 09:26:49 +0000 |
commit | cdbd60fe53f64f08efcf9715c4655e38cd1d7ddd (patch) | |
tree | f1d81b7d84fc7c126dd22f6d3a4e6acf7db019ea | |
parent | b125bb6b6aa095fc287f279a13e6ff423deb3b0f (diff) | |
download | servo-cdbd60fe53f64f08efcf9715c4655e38cd1d7ddd.tar.gz servo-cdbd60fe53f64f08efcf9715c4655e38cd1d7ddd.zip |
Extend character-based soft wrap prevention to before atomics (#30800)
The changes in #30740, fixed an issue where certain characters should
prevent line break opportunity after atomics. This change extends that
to also apply to before atomics, which is what the specification says
should happen.
13 files changed, 41 insertions, 38 deletions
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 9c0a0e25fe1..552b01b6331 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -375,6 +375,12 @@ struct InlineFormattingContextState<'a, 'b> { /// is encountered. have_deferred_soft_wrap_opportunity: bool, + /// Whether or not a soft wrap opportunity should be prevented before the next atomic + /// element encountered in the inline formatting context. See + /// `char_prevents_soft_wrap_opportunity_when_before_or_after_atomic` for more + /// details. + prevent_soft_wrap_opportunity_before_next_atomic: bool, + /// The currently white-space setting of this line. This is stored on the /// [`InlineFormattingContextState`] because when a soft wrap opportunity is defined /// by the boundary between two characters, the white-space property of their nearest @@ -1260,6 +1266,7 @@ impl InlineFormattingContext { white_space: containing_block.style.get_inherited_text().white_space, linebreaker: None, have_deferred_soft_wrap_opportunity: false, + prevent_soft_wrap_opportunity_before_next_atomic: false, root_nesting_level: InlineContainerState { nested_block_size: line_height_from_style(layout_context, &containing_block.style), has_content: false, @@ -1541,7 +1548,11 @@ impl IndependentFormattingContext { }, }; - if ifc.white_space.allow_wrap() { + let soft_wrap_opportunity_prevented = mem::replace( + &mut ifc.prevent_soft_wrap_opportunity_before_next_atomic, + false, + ); + if ifc.white_space.allow_wrap() && !soft_wrap_opportunity_prevented { ifc.process_soft_wrap_opportunity(); } @@ -1683,25 +1694,20 @@ impl TextRun { mem::replace(&mut ifc.have_deferred_soft_wrap_opportunity, false); let mut break_at_start = break_at_start || have_deferred_soft_wrap_opportunity; - // From https://www.w3.org/TR/css-text-3/#line-break-details: - // - // > For Web-compatibility there is a soft wrap opportunity before and after each - // > replaced element or other atomic inline, even when adjacent to a character that - // > would normally suppress them, including U+00A0 NO-BREAK SPACE. However, with - // > the exception of U+00A0 NO-BREAK SPACE, there must be no soft wrap opportunity - // > between atomic inlines and adjacent characters belonging to the Unicode GL, WJ, - // > or ZWJ line breaking classes. if have_deferred_soft_wrap_opportunity { if let Some(first_character) = self.text.chars().nth(0) { - let class = linebreak_property(first_character); break_at_start = break_at_start && - (first_character == '\u{00A0}' || - (class != XI_LINE_BREAKING_CLASS_GL && - class != XI_LINE_BREAKING_CLASS_WJ && - class != XI_LINE_BREAKING_CLASS_ZWJ)); + !char_prevents_soft_wrap_opportunity_when_before_or_after_atomic( + first_character, + ) } } + if let Some(last_character) = self.text.chars().last() { + ifc.prevent_soft_wrap_opportunity_before_next_atomic = + char_prevents_soft_wrap_opportunity_when_before_or_after_atomic(last_character); + } + for (run_index, run) in runs.into_iter().enumerate() { ifc.possibly_flush_deferred_forced_line_break(); @@ -2286,3 +2292,24 @@ impl FloatLineItem { self.fragment } } + +/// Whether or not this character prevents a soft line wrap opportunity when it +/// comes before or after an atomic inline element. +/// +/// From https://www.w3.org/TR/css-text-3/#line-break-details: +/// +/// > For Web-compatibility there is a soft wrap opportunity before and after each +/// > replaced element or other atomic inline, even when adjacent to a character that +/// > would normally suppress them, including U+00A0 NO-BREAK SPACE. However, with +/// > the exception of U+00A0 NO-BREAK SPACE, there must be no soft wrap opportunity +/// > between atomic inlines and adjacent characters belonging to the Unicode GL, WJ, +/// > or ZWJ line breaking classes. +fn char_prevents_soft_wrap_opportunity_when_before_or_after_atomic(character: char) -> bool { + if character == '\u{00A0}' { + return false; + } + let class = linebreak_property(character); + class == XI_LINE_BREAKING_CLASS_GL || + class == XI_LINE_BREAKING_CLASS_WJ || + class == XI_LINE_BREAKING_CLASS_ZWJ +} diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-003.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-003.html.ini deleted file mode 100644 index 8aef227b352..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-003.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-006.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-006.html.ini deleted file mode 100644 index 6045172ba6a..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-006.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-006.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-013.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-013.html.ini deleted file mode 100644 index 9aa5d9e2b4d..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-013.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-013.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-014.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-014.html.ini deleted file mode 100644 index 2f3b3cc709f..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-014.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-014.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-016.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-016.html.ini deleted file mode 100644 index 2cbf8d2756d..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-016.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-016.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-018.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-018.html.ini deleted file mode 100644 index 52d31a10770..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-018.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-018.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-020.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-020.html.ini deleted file mode 100644 index 482939ebb91..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-020.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-020.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-022.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-022.html.ini deleted file mode 100644 index 504c2fccfa5..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-022.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-022.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-024.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-024.html.ini deleted file mode 100644 index 920fd580010..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-024.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-024.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-026.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-026.html.ini deleted file mode 100644 index a44892a287e..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-026.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-atomic-026.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-002.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-002.html.ini deleted file mode 100644 index 2124109d549..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-002.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-replaced-002.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-003.html.ini b/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-003.html.ini deleted file mode 100644 index a414a0f9440..00000000000 --- a/tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[line-breaking-replaced-003.html] - expected: FAIL |