mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
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 <obrufau@igalia.com>
This commit is contained in:
parent
0af1204aa3
commit
8740c03682
3 changed files with 121 additions and 16 deletions
|
@ -2181,15 +2181,25 @@ impl<'a> TableLayout<'a> {
|
|||
area: LogicalSides<usize>,
|
||||
) -> Option<LogicalSides<Au>> {
|
||||
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<LogicalSides<Au>> {
|
||||
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<Au> {
|
||||
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")
|
||||
}
|
||||
|
|
13
tests/wpt/meta/MANIFEST.json
vendored
13
tests/wpt/meta/MANIFEST.json
vendored
|
@ -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",
|
||||
[
|
||||
|
|
88
tests/wpt/tests/css/CSS2/tables/border-collapse-006.html
vendored
Normal file
88
tests/wpt/tests/css/CSS2/tables/border-collapse-006.html
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test (Tables): collapsing borders with different widths</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS2/tables.html#collapsing-borders" />
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
|
||||
<style>
|
||||
table { border-collapse: collapse; background: green }
|
||||
td { padding: 0; background: red; }
|
||||
td div { height: 25px; background: green; }
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<div style="float: left; min-width: 200px; background: red">
|
||||
<!--
|
||||
https://drafts.csswg.org/css2/#collapsing-borders
|
||||
> Borders are centered on the grid lines between the cells.
|
||||
|
||||
That is, the column needs to be big enough to contain:
|
||||
- Half of the left border form the 1st row, i.e. 75px.
|
||||
- Half of the right border form the 2nd row, i.e. 50px.
|
||||
|
||||
Therefore, the column is max(75px, 50px) = 75px wide,
|
||||
and it goes from position 75px to position 150px.
|
||||
|
||||
In the 1st row there is no remaining available space,
|
||||
so the div becomes 0px wide.
|
||||
|
||||
In the 2nd row there are 75px - 50px = 25px of available space,
|
||||
so the div becomes 25px wide.
|
||||
-->
|
||||
<table>
|
||||
<tr>
|
||||
<td style="border-left: 150px solid green">
|
||||
<div></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border-right: 100px solid green">
|
||||
<div></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Same situation, but with explicit widths on the divs -->
|
||||
<table>
|
||||
<tr>
|
||||
<td style="border-left: 150px solid green">
|
||||
<div style="width: 0px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border-right: 100px solid green">
|
||||
<div style="width: 25px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Same situation, but with the rows swapped -->
|
||||
<table>
|
||||
<tr>
|
||||
<td style="border-right: 100px solid green">
|
||||
<div></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border-left: 150px solid green">
|
||||
<div></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Same situation, but with explicit widths and the rows swapped -->
|
||||
<table>
|
||||
<tr>
|
||||
<td style="border-left: 150px solid green">
|
||||
<div style="width: 0px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border-right: 100px solid green">
|
||||
<div style="width: 25px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue