From 8740c03682c2108146fca7a3ba5a7a145ca0d5c3 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Thu, 23 Jan 2025 03:17:06 -0800 Subject: [PATCH] layout: Fix table geometry when collapsed borders have different sizes (#35122) Even though when painting the collapsed borders we were using the right size, when sizing the table we were treating cells as having a border of half the maximum border size along the entire grid line. Now we only take the maximum among the borders adjacent to the cell. Signed-off-by: Oriol Brufau --- components/layout_2020/table/layout.rs | 36 ++++---- tests/wpt/meta/MANIFEST.json | 13 +++ .../css/CSS2/tables/border-collapse-006.html | 88 +++++++++++++++++++ 3 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 tests/wpt/tests/css/CSS2/tables/border-collapse-006.html diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index d8539953f95..dc5d4adc66e 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -2181,15 +2181,25 @@ impl<'a> TableLayout<'a> { area: LogicalSides, ) -> Option> { let collapsed_borders = self.collapsed_borders.as_ref()?; - let inline_start = &collapsed_borders.inline[area.inline_start]; - let inline_end = &collapsed_borders.inline[area.inline_end]; - let block_start = &collapsed_borders.block[area.block_start]; - let block_end = &collapsed_borders.block[area.block_end]; + let columns = || area.inline_start..area.inline_end; + let rows = || area.block_start..area.block_end; + let max_width = |slice: &[CollapsedBorder]| { + let slice_widths = slice.iter().map(|collapsed_border| collapsed_border.width); + slice_widths.max().unwrap_or_default() + }; + Some(area.map_inline_and_block_axes( + |column| max_width(&collapsed_borders.inline[*column].list[rows()]) / 2, + |row| max_width(&collapsed_borders.block[*row].list[columns()]) / 2, + )) + } + + fn get_collapsed_border_widths_for_table(&self) -> Option> { + let collapsed_borders = self.collapsed_borders.as_ref()?; Some(LogicalSides { - inline_start: inline_start.max_width / 2, - inline_end: inline_end.max_width / 2, - block_start: block_start.max_width / 2, - block_end: block_end.max_width / 2, + inline_start: collapsed_borders.inline[0].max_width / 2, + inline_end: collapsed_borders.inline[self.table.size.width].max_width / 2, + block_start: collapsed_borders.block[0].max_width / 2, + block_end: collapsed_borders.block[self.table.size.height].max_width / 2, }) } } @@ -2705,19 +2715,13 @@ impl TableLayoutStyle<'_> { pub(crate) fn halved_collapsed_border_widths(&self) -> LogicalSides { debug_assert!(self.collapses_borders()); - let area = LogicalSides { - inline_start: 0, - inline_end: self.table.size.width, - block_start: 0, - block_end: self.table.size.height, - }; if let Some(layout) = self.layout { - layout.get_collapsed_border_widths_for_area(area) + layout.get_collapsed_border_widths_for_table() } else { // TODO: this should be cached. let mut layout = TableLayout::new(self.table); layout.compute_border_collapse(self.style().writing_mode); - layout.get_collapsed_border_widths_for_area(area) + layout.get_collapsed_border_widths_for_table() } .expect("Collapsed borders should be computed") } diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 9c6cff9ee10..bedcc95fde1 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -105335,6 +105335,19 @@ {} ] ], + "border-collapse-006.html": [ + "f96c40cf95075703a67e9b13ef5b6f9e4e663ff8", + [ + null, + [ + [ + "/css/reference/ref-filled-green-200px-square.html", + "==" + ] + ], + {} + ] + ], "border-collapse-applies-to-016.xht": [ "f102d6a799b195388f57396024532947e3357303", [ diff --git a/tests/wpt/tests/css/CSS2/tables/border-collapse-006.html b/tests/wpt/tests/css/CSS2/tables/border-collapse-006.html new file mode 100644 index 00000000000..f96c40cf950 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/tables/border-collapse-006.html @@ -0,0 +1,88 @@ + + +CSS Test (Tables): collapsing borders with different widths + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+ + + + + + + + +
+
+
+
+
+ + + + + + + + + +
+
+
+
+
+ + + + + + + + + +
+
+
+
+
+ + + + + + + + + +
+
+
+
+
+