diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 2aad6fcca4886..5f2e8fc9dd5b6 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -47,9 +47,10 @@ use crate::fragment_tree::{ BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag, TextFragment, }; -use crate::geom::{LengthPercentageOrAuto, PhysicalPoint, PhysicalRect}; +use crate::geom::{LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize}; use crate::replaced::NaturalSizes; use crate::style_ext::{BorderStyleColor, ComputedValuesExt}; +use crate::table::SpecificTableGridInfo; mod background; mod clip_path; @@ -893,62 +894,119 @@ impl<'a> BuilderForBoxFragment<'a> { } } - fn build_border(&mut self, builder: &mut DisplayListBuilder) { - use crate::geom::PhysicalSides; - use crate::geom::PhysicalSize; - if let Some(SpecificLayoutInfo::TableGrid(table_info)) = &self.fragment.detailed_layout_info { - /*let none = wr::BorderSide { - color: wr::ColorF::TRANSPARENT, - style: wr::BorderStyle::None, - };*/ - let mut common = builder.common_properties(units::LayoutRect::default(), &self.fragment.style); - let mut column_sum = Au::zero(); - println!("# table_info.track_sizes {:?}", table_info.track_sizes); - println!("# table_info.collapsed_borders {:?}", table_info.collapsed_borders); - for (x, column_size) in table_info.track_sizes.x.iter().enumerate() { - let mut row_sum = Au::zero(); - for (y, row_size) in table_info.track_sizes.y.iter().enumerate() { - println!("x={:?}, y={:?}", x, y); - let border_widths = PhysicalSides::new( - table_info.collapsed_borders.y[y].list[x].width, - table_info.collapsed_borders.x[x + 1].list[y].width, - table_info.collapsed_borders.y[y + 1].list[x].width, - table_info.collapsed_borders.x[x].list[y].width, - ); - println!(" border_widths {:?}", border_widths); - let details = wr::BorderDetails::Normal(wr::NormalBorder { - left: self.build_border_side(table_info.collapsed_borders.x[x].list[y].style_color.clone()), - right: self.build_border_side(table_info.collapsed_borders.x[x + 1].list[y].style_color.clone()), - top: self.build_border_side(table_info.collapsed_borders.y[y].list[x].style_color.clone()), - bottom: self.build_border_side(table_info.collapsed_borders.y[y + 1].list[x].style_color.clone()), - radius: wr::BorderRadius::default(), - do_aa: true, - }); - let border_rect = PhysicalRect::new( - PhysicalPoint::new(column_sum, row_sum), - PhysicalSize::new(*column_size, *row_size), - ); - println!(" border_rect {:?}", border_rect); - println!(" self.fragment.content_rect {:?}", self.fragment.content_rect); - println!(" self.containing_block {:?}", self.containing_block); - let border_rect = border_rect - .translate(self.fragment.content_rect.origin.to_vector()) - .translate(self.containing_block.origin.to_vector()); - println!(" final border_rect {:?}", border_rect); - println!(""); - let border_rect = border_rect.to_webrender(); - common.clip_rect = border_rect; - builder - .wr() - .push_border(&common, border_rect, border_widths.to_webrender(), details); - row_sum += *row_size; + fn build_table_collapsed_borders(&mut self, builder: &mut DisplayListBuilder, table_info: &SpecificTableGridInfo) { + let none = wr::BorderSide { + color: wr::ColorF::TRANSPARENT, + style: wr::BorderStyle::None, + }; + let mut common = builder.common_properties(units::LayoutRect::default(), &self.fragment.style); + let mut column_sum = Au::zero(); + println!("# table_info.track_sizes {:?}", table_info.track_sizes); + println!("# table_info.collapsed_borders {:?}", table_info.collapsed_borders); + for (x, column_size) in table_info.track_sizes.x.iter().enumerate() { + let mut row_sum = Au::zero(); + for (y, row_size) in table_info.track_sizes.y.iter().enumerate() { + println!("x={:?}, y={:?}", x, y); + let left_border = &table_info.collapsed_borders.x[x].list[y]; + let right_border = &table_info.collapsed_borders.x[x + 1].list[y]; + let top_border = &table_info.collapsed_borders.y[y].list[x]; + let bottom_border = &table_info.collapsed_borders.y[y + 1].list[x]; + let border_widths = PhysicalSides::new( + if y == 0 { + top_border.width + } else { + Au::zero() + }, + right_border.width, + bottom_border.width, + if x == 0 { + left_border.width + } else { + Au::zero() + }, + ); + + println!(" border_widths {:?}", border_widths); + let mut details = wr::NormalBorder { + left: self.build_border_side(left_border.style_color.clone()), + right: self.build_border_side(right_border.style_color.clone()), + top: self.build_border_side(top_border.style_color.clone()), + bottom: self.build_border_side(bottom_border.style_color.clone()), + radius: wr::BorderRadius::default(), + do_aa: true, + }; + if x > 0 { + details.left = none; + } + let details = wr::BorderDetails::Normal(details); + let mut origin = PhysicalPoint::new(column_sum, row_sum); + if x > 0 { + origin.x += left_border.width / 2; + } + if y > 0 { + origin.y += top_border.width / 2; + } + let mut size = PhysicalSize::new(*column_size, *row_size); + if x > 0 { + size.width -= left_border.width / 2; + } + if y > 0 { + size.height -= top_border.width / 2; } - column_sum += *column_size; + if x + 1 < table_info.track_sizes.x.len() { + size.width += border_widths.right / 2; + } + if y + 1 < table_info.track_sizes.y.len() { + size.height += border_widths.bottom / 2; + } + let border_rect = PhysicalRect::new( + origin, + size, + ); + println!(" border_rect {:?}", border_rect); + println!(" self.fragment.content_rect {:?}", self.fragment.content_rect); + println!(" self.containing_block {:?}", self.containing_block); + let border_rect = border_rect + .translate(self.fragment.content_rect.origin.to_vector()) + .translate(self.containing_block.origin.to_vector()); + println!(" final border_rect {:?}", border_rect); + println!(""); + let border_rect = border_rect.to_webrender(); + common.clip_rect = border_rect; + builder + .wr() + .push_border(&common, border_rect, border_widths.to_webrender(), details); + row_sum += *row_size; } + column_sum += *column_size; + } + } + + fn build_border(&mut self, builder: &mut DisplayListBuilder) { + match &self.fragment.detailed_layout_info { + Some(SpecificLayoutInfo::TableGrid(table_info)) => { + self.build_table_collapsed_borders(builder, table_info); + return; + }, + Some(SpecificLayoutInfo::TableCell) => { + // Avoid painting borders for table cells in collapsed-borders mode, + // since they are painted with the table grid. + return; + }, + _ => {}, + } + + use style::values::specified::box_::DisplayInside; + use style::computed_values::border_collapse::T as BorderCollapse; + if self.fragment.style.get_box().display.inside() == DisplayInside::Table && + self.fragment.style.get_inherited_table().border_collapse == BorderCollapse::Collapse + { + // Avoid painting borders for a table wrapper in collapsed-borders mode, + // since they are painted with the table grid. return; } - /*let border = self.fragment.style.get_border(); + let border = self.fragment.style.get_border(); let border_widths = self.fragment.border.to_webrender(); if border_widths == SideOffsets2D::zero() { @@ -972,7 +1030,7 @@ impl<'a> BuilderForBoxFragment<'a> { }); builder .wr() - .push_border(&common, self.border_rect, border_widths, details)*/ + .push_border(&common, self.border_rect, border_widths, details) } /// Add a display item for image borders if necessary. diff --git a/components/layout_2020/fragment_tree/box_fragment.rs b/components/layout_2020/fragment_tree/box_fragment.rs index 29625db299976..8d1aef00874af 100644 --- a/components/layout_2020/fragment_tree/box_fragment.rs +++ b/components/layout_2020/fragment_tree/box_fragment.rs @@ -44,6 +44,7 @@ pub(crate) struct ExtraBackground { pub(crate) enum SpecificLayoutInfo { Grid(Box), TableGrid(Box), + TableCell, } pub(crate) struct BoxFragment { diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index a2f041a0a514b..62bd9886841de 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -1991,12 +1991,19 @@ impl<'a> TableLayout<'a> { } fn detailed_layout_info(&mut self) -> Option { - mem::take(&mut self.collapsed_borders).map(|collapsed_borders| { + mem::take(&mut self.collapsed_borders).map(|mut collapsed_borders| { let writing_mode = self.table.style.writing_mode; - let track_sizes = LogicalVec2 { + let mut track_sizes = LogicalVec2 { inline: mem::take(&mut self.distributed_column_widths), block: mem::take(&mut self.row_sizes), }; + if !writing_mode.is_bidi_ltr() { + track_sizes.inline.reverse(); + collapsed_borders.inline.reverse(); + for border_line in &mut collapsed_borders.block { + border_line.list.reverse(); + } + } SpecificLayoutInfo::TableGrid(Box::new(SpecificTableGridInfo { collapsed_borders: if writing_mode.is_horizontal() { PhysicalVec::new(collapsed_borders.inline, collapsed_borders.block) @@ -2882,6 +2889,8 @@ impl TableSlotCell { ); positioning_context.append(layout.positioning_context); + let detailed_layout_info = (table_style.get_inherited_table().border_collapse == BorderCollapse::Collapse).then_some(SpecificLayoutInfo::TableCell); + BoxFragment::new( base_fragment_info, self.base.style.clone(), @@ -2894,6 +2903,7 @@ impl TableSlotCell { CollapsedBlockMargins::zero(), ) .with_baselines(layout.layout.baselines) + .with_detailed_layout_info(detailed_layout_info) } } diff --git a/tests/wpt/tests/css/CSS2/tables/fixed-table-layout-003f01.xht b/tests/wpt/tests/css/CSS2/tables/fixed-table-layout-003f01.xht index 275e8645c0b0c..db692011d54b5 100644 --- a/tests/wpt/tests/css/CSS2/tables/fixed-table-layout-003f01.xht +++ b/tests/wpt/tests/css/CSS2/tables/fixed-table-layout-003f01.xht @@ -27,9 +27,10 @@ td#tested-cell { - background-color: blue; + background: blue; border-left: orange solid 60px; border-right: orange solid 60px; + border-color: rgba(255, 255, 0, 0.5); color: blue; width: 80px; }