mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Paint collapsed table borders on their own (#35075)
We were previously splitting collapsed borders into two halves, and then paint each one as part of the corresponding cell. This looked wrong when the border style wasn't solid, or when a cell spanned multiple tracks and the border wasn't the same for all of them. Now the borders of a table wrapper, table grid or table cell aren't painted in collapsed borders mode. Instead, the resulting collapsed borders are painted on their own. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
e43baed585
commit
d00d76c1e8
15 changed files with 208 additions and 124 deletions
|
@ -47,7 +47,9 @@ 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};
|
||||
|
||||
|
@ -650,9 +652,16 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
if section == StackingContextSection::Outline {
|
||||
self.build_outline(builder);
|
||||
return;
|
||||
match section {
|
||||
StackingContextSection::CollapsedTableBorders => {
|
||||
self.build_collapsed_table_borders(builder);
|
||||
return;
|
||||
},
|
||||
StackingContextSection::Outline => {
|
||||
self.build_outline(builder);
|
||||
return;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
self.build_hit_test(builder, self.border_rect);
|
||||
|
@ -893,7 +902,90 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_collapsed_table_borders(&mut self, builder: &mut DisplayListBuilder) {
|
||||
let Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(table_info)) =
|
||||
&self.fragment.detailed_layout_info
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let mut common =
|
||||
builder.common_properties(units::LayoutRect::default(), &self.fragment.style);
|
||||
let radius = wr::BorderRadius::default();
|
||||
let mut column_sum = Au::zero();
|
||||
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() {
|
||||
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 details = wr::BorderDetails::Normal(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,
|
||||
do_aa: true,
|
||||
});
|
||||
let mut border_widths = PhysicalSides::new(
|
||||
top_border.width,
|
||||
right_border.width,
|
||||
bottom_border.width,
|
||||
left_border.width,
|
||||
);
|
||||
|
||||
let mut origin = PhysicalPoint::new(column_sum, row_sum);
|
||||
let mut size = PhysicalSize::new(*column_size, *row_size);
|
||||
if x == 0 {
|
||||
origin.x -= table_info.wrapper_border.left;
|
||||
size.width += table_info.wrapper_border.left;
|
||||
} else {
|
||||
border_widths.left = Au::zero();
|
||||
origin.x += left_border.width / 2;
|
||||
size.width -= left_border.width / 2;
|
||||
}
|
||||
if y == 0 {
|
||||
origin.y -= table_info.wrapper_border.top;
|
||||
size.height += table_info.wrapper_border.top;
|
||||
} else {
|
||||
border_widths.top = Au::zero();
|
||||
origin.y += top_border.width / 2;
|
||||
size.height -= top_border.width / 2;
|
||||
}
|
||||
if x + 1 == table_info.track_sizes.x.len() {
|
||||
size.width += table_info.wrapper_border.right;
|
||||
} else {
|
||||
size.width += border_widths.right / 2;
|
||||
}
|
||||
if y + 1 == table_info.track_sizes.y.len() {
|
||||
size.height += table_info.wrapper_border.bottom;
|
||||
} else {
|
||||
size.height += border_widths.bottom / 2;
|
||||
}
|
||||
let border_rect = PhysicalRect::new(origin, size)
|
||||
.translate(self.fragment.content_rect.origin.to_vector())
|
||||
.translate(self.containing_block.origin.to_vector())
|
||||
.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) {
|
||||
if self.fragment.has_collapsed_borders() {
|
||||
// Avoid painting borders for tables and table parts in collapsed-borders mode,
|
||||
// since the resulting collapsed borders are painted on their own in a special way.
|
||||
return;
|
||||
}
|
||||
|
||||
let border = self.fragment.style.get_border();
|
||||
let border_widths = self.fragment.border.to_webrender();
|
||||
|
||||
|
@ -907,12 +999,7 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
let style_color = match &self.fragment.detailed_layout_info {
|
||||
Some(SpecificLayoutInfo::TableGridOrTableCell(table_info)) => {
|
||||
table_info.border_style_color.clone()
|
||||
},
|
||||
_ => BorderStyleColor::from_border(border),
|
||||
};
|
||||
let style_color = BorderStyleColor::from_border(border);
|
||||
let details = wr::BorderDetails::Normal(wr::NormalBorder {
|
||||
top: self.build_border_side(style_color.top),
|
||||
right: self.build_border_side(style_color.right),
|
||||
|
|
|
@ -34,7 +34,8 @@ use super::DisplayList;
|
|||
use crate::display_list::conversions::{FilterToWebRender, ToWebRender};
|
||||
use crate::display_list::{BuilderForBoxFragment, DisplayListBuilder};
|
||||
use crate::fragment_tree::{
|
||||
BoxFragment, ContainingBlockManager, Fragment, FragmentFlags, FragmentTree, PositioningFragment,
|
||||
BoxFragment, ContainingBlockManager, Fragment, FragmentFlags, FragmentTree,
|
||||
PositioningFragment, SpecificLayoutInfo,
|
||||
};
|
||||
use crate::geom::{AuOrAuto, PhysicalRect, PhysicalSides};
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
|
@ -87,6 +88,7 @@ pub(crate) type ContainingBlockInfo<'a> = ContainingBlockManager<'a, ContainingB
|
|||
pub(crate) enum StackingContextSection {
|
||||
OwnBackgroundsAndBorders,
|
||||
DescendantBackgroundsAndBorders,
|
||||
CollapsedTableBorders,
|
||||
Foreground,
|
||||
Outline,
|
||||
}
|
||||
|
@ -726,6 +728,16 @@ impl StackingContext {
|
|||
child.build_display_list(builder, &self.atomic_inline_stacking_containers);
|
||||
}
|
||||
|
||||
// Additional step 4.5: Collapsed table borders
|
||||
// This step isn't in the spec, but other browsers seem to paint them at this point.
|
||||
while contents.peek().is_some_and(|(_, child)| {
|
||||
child.section() == StackingContextSection::CollapsedTableBorders
|
||||
}) {
|
||||
let (i, child) = contents.next().unwrap();
|
||||
self.debug_push_print_item(DebugPrintField::Contents, i);
|
||||
child.build_display_list(builder, &self.atomic_inline_stacking_containers);
|
||||
}
|
||||
|
||||
// Step 5: Float stacking containers
|
||||
for (i, child) in self.float_stacking_containers.iter().enumerate() {
|
||||
self.debug_push_print_item(DebugPrintField::FloatStackingContainers, i);
|
||||
|
@ -1181,30 +1193,34 @@ impl BoxFragment {
|
|||
.for_absolute_and_fixed_descendants
|
||||
.scroll_node_id
|
||||
};
|
||||
stacking_context
|
||||
.contents
|
||||
.push(StackingContextContent::Fragment {
|
||||
scroll_node_id: new_scroll_node_id,
|
||||
reference_frame_scroll_node_id: reference_frame_scroll_node_id_for_fragments,
|
||||
clip_chain_id: new_clip_chain_id,
|
||||
section: self.get_stacking_context_section(),
|
||||
containing_block: containing_block.rect,
|
||||
fragment: fragment.clone(),
|
||||
is_hit_test_for_scrollable_overflow: false,
|
||||
});
|
||||
|
||||
if !self.style.get_outline().outline_width.is_zero() {
|
||||
let mut add_fragment = |section| {
|
||||
stacking_context
|
||||
.contents
|
||||
.push(StackingContextContent::Fragment {
|
||||
scroll_node_id: new_scroll_node_id,
|
||||
reference_frame_scroll_node_id: reference_frame_scroll_node_id_for_fragments,
|
||||
clip_chain_id: new_clip_chain_id,
|
||||
section: StackingContextSection::Outline,
|
||||
section,
|
||||
containing_block: containing_block.rect,
|
||||
fragment: fragment.clone(),
|
||||
is_hit_test_for_scrollable_overflow: false,
|
||||
});
|
||||
};
|
||||
|
||||
add_fragment(self.get_stacking_context_section());
|
||||
|
||||
if let Fragment::Box(box_fragment) = &fragment {
|
||||
if matches!(
|
||||
box_fragment.borrow().detailed_layout_info,
|
||||
Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_))
|
||||
) {
|
||||
add_fragment(StackingContextSection::CollapsedTableBorders);
|
||||
}
|
||||
}
|
||||
|
||||
if !self.style.get_outline().outline_width.is_zero() {
|
||||
add_fragment(StackingContextSection::Outline);
|
||||
}
|
||||
|
||||
// We want to build the scroll frame after the background and border, because
|
||||
|
|
|
@ -6,6 +6,7 @@ use app_units::Au;
|
|||
use atomic_refcell::AtomicRefCell;
|
||||
use base::print_tree::PrintTree;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use style::computed_values::border_collapse::T as BorderCollapse;
|
||||
use style::computed_values::overflow_x::T as ComputedOverflow;
|
||||
use style::computed_values::position::T as ComputedPosition;
|
||||
use style::logical_geometry::WritingMode;
|
||||
|
@ -19,7 +20,7 @@ use crate::geom::{
|
|||
AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical,
|
||||
};
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use crate::table::SpecificTableGridOrTableCellInfo;
|
||||
use crate::table::SpecificTableGridInfo;
|
||||
use crate::taffy::SpecificTaffyGridInfo;
|
||||
|
||||
/// Describes how a [`BoxFragment`] paints its background.
|
||||
|
@ -43,7 +44,8 @@ pub(crate) struct ExtraBackground {
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum SpecificLayoutInfo {
|
||||
Grid(Box<SpecificTaffyGridInfo>),
|
||||
TableGridOrTableCell(Box<SpecificTableGridOrTableCellInfo>),
|
||||
TableCellWithCollapsedBorders,
|
||||
TableGridWithCollapsedBorders(Box<SpecificTableGridInfo>),
|
||||
TableWrapper,
|
||||
}
|
||||
|
||||
|
@ -356,4 +358,15 @@ impl BoxFragment {
|
|||
Some(SpecificLayoutInfo::TableWrapper)
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn has_collapsed_borders(&self) -> bool {
|
||||
match &self.detailed_layout_info {
|
||||
Some(SpecificLayoutInfo::TableCellWithCollapsedBorders) => true,
|
||||
Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) => true,
|
||||
Some(SpecificLayoutInfo::TableWrapper) => {
|
||||
self.style.get_inherited_table().border_collapse == BorderCollapse::Collapse
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use core::cmp::Ordering;
|
||||
use std::mem;
|
||||
use std::ops::Range;
|
||||
|
||||
use app_units::{Au, MAX_AU};
|
||||
|
@ -24,7 +25,8 @@ use style::values::generics::box_::{GenericVerticalAlign as VerticalAlign, Verti
|
|||
use style::Zero;
|
||||
|
||||
use super::{
|
||||
ArcRefCell, Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup,
|
||||
ArcRefCell, CollapsedBorder, CollapsedBorderLine, SpecificTableGridInfo, Table, TableCaption,
|
||||
TableSlot, TableSlotCell, TableSlotCoordinates, TableTrack, TableTrackGroup,
|
||||
};
|
||||
use crate::context::LayoutContext;
|
||||
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
||||
|
@ -34,29 +36,17 @@ use crate::fragment_tree::{
|
|||
};
|
||||
use crate::geom::{
|
||||
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
|
||||
Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
|
||||
PhysicalVec, Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
|
||||
};
|
||||
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{
|
||||
BorderStyleColor, Clamp, ComputedValuesExt, LayoutStyle, PaddingBorderMargin,
|
||||
};
|
||||
use crate::table::{SpecificTableGridOrTableCellInfo, TableSlotCoordinates};
|
||||
use crate::{
|
||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
|
||||
};
|
||||
|
||||
fn detailed_layout_info(
|
||||
border_style_color: Option<LogicalSides<BorderStyleColor>>,
|
||||
writing_mode: WritingMode,
|
||||
) -> Option<SpecificLayoutInfo> {
|
||||
Some(SpecificLayoutInfo::TableGridOrTableCell(Box::new(
|
||||
SpecificTableGridOrTableCellInfo {
|
||||
border_style_color: border_style_color?.to_physical(writing_mode),
|
||||
},
|
||||
)))
|
||||
}
|
||||
|
||||
/// A result of a final or speculative layout of a single cell in
|
||||
/// the table. Note that this is only done for slots that are not
|
||||
/// covered by spans or empty.
|
||||
|
@ -64,7 +54,6 @@ struct CellLayout {
|
|||
layout: IndependentLayout,
|
||||
padding: LogicalSides<Au>,
|
||||
border: LogicalSides<Au>,
|
||||
detailed_layout_info: Option<SpecificLayoutInfo>,
|
||||
positioning_context: PositioningContext,
|
||||
}
|
||||
|
||||
|
@ -113,13 +102,6 @@ struct ColumnLayout {
|
|||
percentage: Percentage,
|
||||
}
|
||||
|
||||
/// A calculated collapsed border.
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
struct CollapsedBorder {
|
||||
style_color: BorderStyleColor,
|
||||
width: Au,
|
||||
}
|
||||
|
||||
impl CollapsedBorder {
|
||||
fn new(style_color: BorderStyleColor, width: Au) -> Self {
|
||||
Self { style_color, width }
|
||||
|
@ -180,13 +162,6 @@ impl PartialOrd for CollapsedBorder {
|
|||
|
||||
impl Eq for CollapsedBorder {}
|
||||
|
||||
/// Represents a piecewise sequence of collapsed borders along a line.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct CollapsedBorderLine {
|
||||
max_width: Au,
|
||||
list: Vec<CollapsedBorder>,
|
||||
}
|
||||
|
||||
impl CollapsedBorderLine {
|
||||
fn max_assign(&mut self, collapsed_border: &CollapsedBorder, range: &Range<usize>) {
|
||||
self.max_width.max_assign(collapsed_border.width);
|
||||
|
@ -196,9 +171,6 @@ impl CollapsedBorderLine {
|
|||
}
|
||||
}
|
||||
|
||||
/// The calculated collapsed borders.
|
||||
type CollapsedBorders = LogicalVec2<Vec<CollapsedBorderLine>>;
|
||||
|
||||
/// A helper struct that performs the layout of the box tree version
|
||||
/// of a table into the fragment tree version. This implements
|
||||
/// <https://drafts.csswg.org/css-tables/#table-layout-algorithm>
|
||||
|
@ -222,7 +194,7 @@ pub(crate) struct TableLayout<'a> {
|
|||
cells_laid_out: Vec<Vec<Option<CellLayout>>>,
|
||||
basis_for_cell_padding_percentage: Au,
|
||||
/// Information about collapsed borders.
|
||||
collapsed_borders: Option<CollapsedBorders>,
|
||||
collapsed_borders: Option<LogicalVec2<Vec<CollapsedBorderLine>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -1213,10 +1185,6 @@ impl<'a> TableLayout<'a> {
|
|||
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 layout_style = cell.layout_style();
|
||||
let border = self
|
||||
.get_collapsed_border_widths_for_area(area)
|
||||
|
@ -1257,7 +1225,6 @@ impl<'a> TableLayout<'a> {
|
|||
layout,
|
||||
padding,
|
||||
border,
|
||||
detailed_layout_info,
|
||||
positioning_context,
|
||||
})
|
||||
})
|
||||
|
@ -1870,14 +1837,6 @@ 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.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, table_writing_mode);
|
||||
|
||||
if self.table.size.width == 0 && self.table.size.height == 0 {
|
||||
let content_rect = LogicalRect {
|
||||
start_corner: LogicalVec2::zero(),
|
||||
|
@ -1898,7 +1857,7 @@ impl<'a> TableLayout<'a> {
|
|||
None, /* clearance */
|
||||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
.with_detailed_layout_info(detailed_layout_info);
|
||||
.with_detailed_layout_info(self.specific_layout_info_for_grid());
|
||||
}
|
||||
|
||||
let mut table_fragments = Vec::new();
|
||||
|
@ -2025,7 +1984,37 @@ impl<'a> TableLayout<'a> {
|
|||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
.with_baselines(baselines)
|
||||
.with_detailed_layout_info(detailed_layout_info)
|
||||
.with_detailed_layout_info(self.specific_layout_info_for_grid())
|
||||
}
|
||||
|
||||
fn specific_layout_info_for_grid(&mut self) -> Option<SpecificLayoutInfo> {
|
||||
mem::take(&mut self.collapsed_borders).map(|mut collapsed_borders| {
|
||||
let writing_mode = self.table.style.writing_mode;
|
||||
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::TableGridWithCollapsedBorders(Box::new(SpecificTableGridInfo {
|
||||
collapsed_borders: if writing_mode.is_horizontal() {
|
||||
PhysicalVec::new(collapsed_borders.inline, collapsed_borders.block)
|
||||
} else {
|
||||
PhysicalVec::new(collapsed_borders.block, collapsed_borders.inline)
|
||||
},
|
||||
track_sizes: if writing_mode.is_horizontal() {
|
||||
PhysicalVec::new(track_sizes.inline, track_sizes.block)
|
||||
} else {
|
||||
PhysicalVec::new(track_sizes.block, track_sizes.inline)
|
||||
},
|
||||
wrapper_border: self.pbm.border.to_physical(writing_mode),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
fn is_row_collapsed(&self, row_index: usize) -> bool {
|
||||
|
@ -2212,7 +2201,7 @@ impl<'a> TableLayout<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut collapsed_borders = CollapsedBorders {
|
||||
let mut collapsed_borders = LogicalVec2 {
|
||||
block: vec![
|
||||
CollapsedBorderLine {
|
||||
max_width: Au::zero(),
|
||||
|
@ -2318,30 +2307,6 @@ impl<'a> TableLayout<'a> {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn get_collapsed_border_style_colors_for_area(
|
||||
&self,
|
||||
area: LogicalSides<usize>,
|
||||
) -> Option<LogicalSides<BorderStyleColor>> {
|
||||
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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct RowFragmentLayout<'a> {
|
||||
|
@ -2922,6 +2887,10 @@ impl TableSlotCell {
|
|||
);
|
||||
positioning_context.append(layout.positioning_context);
|
||||
|
||||
let detailed_layout_info = (table_style.get_inherited_table().border_collapse ==
|
||||
BorderCollapse::Collapse)
|
||||
.then_some(SpecificLayoutInfo::TableCellWithCollapsedBorders);
|
||||
|
||||
BoxFragment::new(
|
||||
base_fragment_info,
|
||||
self.base.style.clone(),
|
||||
|
@ -2934,7 +2903,7 @@ impl TableSlotCell {
|
|||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
.with_baselines(layout.layout.baselines)
|
||||
.with_detailed_layout_info(layout.detailed_layout_info)
|
||||
.with_detailed_layout_info(detailed_layout_info)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ mod layout;
|
|||
|
||||
use std::ops::Range;
|
||||
|
||||
use app_units::Au;
|
||||
pub(crate) use construct::AnonymousTableContent;
|
||||
pub use construct::TableBuilder;
|
||||
use euclid::{Point2D, Size2D, UnknownUnit, Vector2D};
|
||||
|
@ -83,7 +84,7 @@ use crate::cell::ArcRefCell;
|
|||
use crate::flow::BlockContainer;
|
||||
use crate::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::fragment_tree::BaseFragmentInfo;
|
||||
use crate::geom::PhysicalSides;
|
||||
use crate::geom::{PhysicalSides, PhysicalVec};
|
||||
use crate::layout_box_base::LayoutBoxBase;
|
||||
use crate::style_ext::BorderStyleColor;
|
||||
|
||||
|
@ -317,9 +318,23 @@ pub struct TableCaption {
|
|||
context: ArcRefCell<IndependentFormattingContext>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct SpecificTableGridOrTableCellInfo {
|
||||
/// For tables is in collapsed-borders mode, this is used as an override for the
|
||||
/// style and color of the border of the table and table cells.
|
||||
pub border_style_color: PhysicalSides<BorderStyleColor>,
|
||||
/// A calculated collapsed border.
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub(crate) struct CollapsedBorder {
|
||||
pub style_color: BorderStyleColor,
|
||||
pub width: Au,
|
||||
}
|
||||
|
||||
/// Represents a piecewise sequence of collapsed borders along a line.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub(crate) struct CollapsedBorderLine {
|
||||
max_width: Au,
|
||||
pub list: Vec<CollapsedBorder>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct SpecificTableGridInfo {
|
||||
pub collapsed_borders: PhysicalVec<Vec<CollapsedBorderLine>>,
|
||||
pub track_sizes: PhysicalVec<Vec<Au>>,
|
||||
pub wrapper_border: PhysicalSides<Au>,
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[block-formatting-contexts-003.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[border-conflict-element-001d.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[collapsing-border-model-001.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[collapsing-border-model-004.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[box-shadow-table-border-collapse-001.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[ttwf-reftest-borderRadius.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[border-collapse-double-border.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[collapsed-border-paint-phase-002.html]
|
||||
expected: FAIL
|
2
tests/wpt/meta/css/css-tables/collapsed-border-positioned-tr-td.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-tables/collapsed-border-positioned-tr-td.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
[collapsed-border-positioned-tr-td.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[356774-1.html]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue