aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2023-12-01 10:26:49 +0100
committerGitHub <noreply@github.com>2023-12-01 09:26:49 +0000
commitcdbd60fe53f64f08efcf9715c4655e38cd1d7ddd (patch)
treef1d81b7d84fc7c126dd22f6d3a4e6acf7db019ea
parentb125bb6b6aa095fc287f279a13e6ff423deb3b0f (diff)
downloadservo-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.
-rw-r--r--components/layout_2020/flow/inline.rs55
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-003.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-006.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-013.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-014.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-016.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-018.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-020.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-022.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-024.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-atomic-026.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-002.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/line-breaking/line-breaking-replaced-003.html.ini2
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