diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs index ce6b969b1ef..d316f165609 100644 --- a/components/layout_2020/geom.rs +++ b/components/layout_2020/geom.rs @@ -40,7 +40,7 @@ pub struct LogicalRect { pub size: LogicalVec2, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Default)] pub struct LogicalSides { pub inline_start: T, pub inline_end: T, diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index 8b153d05b4b..91af3d59447 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -45,11 +45,12 @@ use crate::{ }; fn detailed_layout_info( - border_style_color: Option>, + border_style_color: Option>, + writing_mode: WritingMode, ) -> Option { Some(SpecificLayoutInfo::TableOrTableCell(Box::new( SpecificTableOrTableCellInfo { - border_style_color: border_style_color?, + border_style_color: border_style_color?.to_physical(writing_mode), }, ))) } @@ -131,9 +132,9 @@ impl CollapsedBorder { } } - fn max_assign(&mut self, other: Self) { - if *self < other { - *self = other; + fn max_assign(&mut self, other: &Self) { + if *self < *other { + *self = other.clone(); } } } @@ -172,13 +173,25 @@ impl PartialOrd for CollapsedBorder { impl Eq for CollapsedBorder {} -/// The calculated collapsed borders. +/// Represents a piecewise sequence of collapsed borders along a line. #[derive(Clone, Debug, Default)] -struct CollapsedBorders { - block: Vec, - inline: Vec, +struct CollapsedBorderLine { + max_width: Au, + list: Vec, } +impl CollapsedBorderLine { + fn max_assign(&mut self, collapsed_border: &CollapsedBorder, range: &Range) { + self.max_width.max_assign(collapsed_border.width); + for index in range.clone() { + self.list[index].max_assign(collapsed_border) + } + } +} + +/// The calculated collapsed borders. +type CollapsedBorders = LogicalVec2>; + /// A helper struct that performs the layout of the box tree version /// of a table into the fragment tree version. This implements /// @@ -279,14 +292,13 @@ impl<'a> TableLayout<'a> { .percentages_relative_to(Au::zero()); let border = self - .get_collapsed_borders_for_cell( - cell, - TableSlotCoordinates::new(column_index, row_index), - ) - .map_or_else( - || cell.base.style.border_width(writing_mode), - |(border, _)| border, - ); + .get_collapsed_border_widths_for_area(LogicalSides { + inline_start: column_index, + inline_end: column_index + cell.colspan, + block_start: row_index, + block_end: row_index + cell.rowspan, + }) + .unwrap_or_else(|| cell.base.style.border_width(writing_mode)); let padding_border_sums = LogicalVec2 { inline: padding.inline_sum() + border.inline_sum(), @@ -1195,22 +1207,23 @@ impl<'a> TableLayout<'a> { return None; }; - let coordinates = TableSlotCoordinates::new(column_index, row_index); - let (border, detailed_layout_info) = - match self.get_collapsed_borders_for_cell(cell, coordinates) { - Some((border_width, border_style_color)) => { - let border_style_color = border_style_color - .to_physical(self.table.style.writing_mode); - (border_width, detailed_layout_info(Some(border_style_color))) - }, - None => ( - cell.base.style.border_width( - containing_block_for_table.style.writing_mode, - ), - None, - ), - }; - + let area = LogicalSides { + inline_start: column_index, + inline_end: column_index + cell.colspan, + block_start: row_index, + block_end: row_index + cell.rowspan, + }; + let detailed_layout_info = detailed_layout_info( + self.get_collapsed_border_style_colors_for_area(area), + self.table.style.writing_mode, + ); + let border = self + .get_collapsed_border_widths_for_area(area) + .unwrap_or_else(|| { + cell.base + .style + .border_width(containing_block_for_table.style.writing_mode) + }); let padding: LogicalSides = cell .base .style @@ -1861,20 +1874,13 @@ impl<'a> TableLayout<'a> { assert_eq!(self.table.size.height, self.row_sizes.len()); assert_eq!(self.table.size.width, self.distributed_column_widths.len()); - let border_style_color = self.collapsed_borders.as_ref().map(|collapsed_borders| { - LogicalSides { - inline_start: collapsed_borders.inline[0].style_color.clone(), - inline_end: collapsed_borders.inline[self.table.size.width] - .style_color - .clone(), - block_start: collapsed_borders.block[0].style_color.clone(), - block_end: collapsed_borders.block[self.table.size.height] - .style_color - .clone(), - } - .to_physical(table_writing_mode) + let border_style_color = self.get_collapsed_border_style_colors_for_area(LogicalSides { + inline_start: 0, + inline_end: self.table.size.width, + block_start: 0, + block_end: self.table.size.height, }); - let detailed_layout_info = detailed_layout_info(border_style_color); + let detailed_layout_info = detailed_layout_info(border_style_color, table_writing_mode); if self.table.size.width == 0 && self.table.size.height == 0 { let content_rect = LogicalRect { @@ -2211,17 +2217,29 @@ impl<'a> TableLayout<'a> { } let mut collapsed_borders = CollapsedBorders { - block: vec![Default::default(); self.table.size.height + 1], - inline: vec![Default::default(); self.table.size.width + 1], + block: vec![ + CollapsedBorderLine { + max_width: Au::zero(), + list: vec![Default::default(); self.table.size.width], + }; + self.table.size.height + 1 + ], + inline: vec![ + CollapsedBorderLine { + max_width: Au::zero(), + list: vec![Default::default(); self.table.size.height], + }; + self.table.size.width + 1 + ], }; let mut apply_border = |style: &ComputedValues, block: &Range, inline: &Range| { let border = CollapsedBorder::from_style(style, writing_mode); - collapsed_borders.block[block.start].max_assign(border.block_start); - collapsed_borders.block[block.end].max_assign(border.block_end); - collapsed_borders.inline[inline.start].max_assign(border.inline_start); - collapsed_borders.inline[inline.end].max_assign(border.inline_end); + collapsed_borders.block[block.start].max_assign(&border.block_start, inline); + collapsed_borders.block[block.end].max_assign(&border.block_end, inline); + collapsed_borders.inline[inline.start].max_assign(&border.inline_start, block); + collapsed_borders.inline[inline.end].max_assign(&border.inline_end, block); }; let all_rows = 0..self.table.size.height; let all_columns = 0..self.table.size.width; @@ -2256,47 +2274,61 @@ impl<'a> TableLayout<'a> { self.collapsed_borders = Some(collapsed_borders); } - fn get_collapsed_borders_for_cell( + fn get_collapsed_border_widths_for_area( &self, - cell: &TableSlotCell, - coordinates: TableSlotCoordinates, - ) -> Option<(LogicalSides, LogicalSides)> { + area: LogicalSides, + ) -> Option> { let collapsed_borders = self.collapsed_borders.as_ref()?; - let end_x = coordinates.x + cell.colspan; - let end_y = coordinates.y + cell.rowspan; - let inline_start = &collapsed_borders.inline[coordinates.x]; - let inline_end = &collapsed_borders.inline[end_x]; - let block_start = &collapsed_borders.block[coordinates.y]; - let block_end = &collapsed_borders.block[end_y]; - let border_width = LogicalSides { - inline_start: if coordinates.x == 0 { - inline_start.width - self.pbm.border.inline_start + 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]; + Some(LogicalSides { + inline_start: if area.inline_start == 0 { + inline_start.max_width - self.pbm.border.inline_start } else { - inline_start.width / 2 + inline_start.max_width / 2 }, - inline_end: if end_x == self.table.size.width { - inline_end.width - self.pbm.border.inline_end + inline_end: if area.inline_end == self.table.size.width { + inline_end.max_width - self.pbm.border.inline_end } else { - inline_end.width / 2 + inline_end.max_width / 2 }, - block_start: if coordinates.y == 0 { - block_start.width - self.pbm.border.block_start + block_start: if area.block_start == 0 { + block_start.max_width - self.pbm.border.block_start } else { - block_start.width / 2 + block_start.max_width / 2 }, - block_end: if end_y == self.table.size.height { - block_end.width - self.pbm.border.block_end + block_end: if area.block_end == self.table.size.height { + block_end.max_width - self.pbm.border.block_end } else { - block_end.width / 2 + block_end.max_width / 2 }, - }; - let border_style_color = LogicalSides { - inline_start: inline_start.style_color.clone(), - inline_end: inline_end.style_color.clone(), - block_start: block_start.style_color.clone(), - block_end: block_end.style_color.clone(), - }; - Some((border_width, border_style_color)) + }) + } + + fn get_collapsed_border_style_colors_for_area( + &self, + area: LogicalSides, + ) -> Option> { + let collapsed_borders = self.collapsed_borders.as_ref()?; + if self.table.size.width == 0 || self.table.size.height == 0 { + return Some(LogicalSides::default()); + } + 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]; + + // This area may span multiple rows and columns, each of which can have different + // collapsed borders. However, we don't have support for one side of a box to have + // a piecewise border. Therefore, we just pick the first piece for the entire side. + Some(LogicalSides { + inline_start: inline_start.list[area.block_start].style_color.clone(), + inline_end: inline_end.list[area.block_start].style_color.clone(), + block_start: block_start.list[area.inline_start].style_color.clone(), + block_end: block_end.list[area.inline_start].style_color.clone(), + }) } } diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-006.xht.ini deleted file mode 100644 index 35ea6d3fada..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-bottom-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-006.xht.ini deleted file mode 100644 index 40f5c78d7cb..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-bottom-color-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-006.xht.ini deleted file mode 100644 index 4d181d00be2..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-bottom-width-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-006.xht.ini deleted file mode 100644 index 27b2aaa4cbf..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-top-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-006.xht.ini deleted file mode 100644 index 099d358ca08..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-top-color-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-006.xht.ini deleted file mode 100644 index 050bbc2da77..00000000000 --- a/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-top-width-applies-to-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/tables/border-collapse-dynamic-cell-002.xht.ini b/tests/wpt/meta/css/CSS2/tables/border-collapse-dynamic-cell-002.xht.ini deleted file mode 100644 index 4a0bc7a2846..00000000000 --- a/tests/wpt/meta/css/CSS2/tables/border-collapse-dynamic-cell-002.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[border-collapse-dynamic-cell-002.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/css-tables/collapsed-border-remove-cell.html.ini b/tests/wpt/meta/css/css-tables/collapsed-border-remove-cell.html.ini deleted file mode 100644 index 6430bb5ee41..00000000000 --- a/tests/wpt/meta/css/css-tables/collapsed-border-remove-cell.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[collapsed-border-remove-cell.html] - expected: FAIL