mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
layout: Improve painting of collapsed borders in table layout (#34933)
This is still not the right approach, because we are not painting collapsed borders as a single thing. Instead, we are splitting them into two halves and paint each half on a different cell. This only looks good for solid borders. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
25a94efcdf
commit
e2be55b873
88 changed files with 181 additions and 256 deletions
|
@ -22,7 +22,7 @@ use style::properties::style_structs::Border;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::image::Image;
|
use style::values::computed::image::Image;
|
||||||
use style::values::computed::{
|
use style::values::computed::{
|
||||||
BorderImageSideWidth, BorderImageWidth, BorderStyle, Color, LengthPercentage,
|
BorderImageSideWidth, BorderImageWidth, BorderStyle, LengthPercentage,
|
||||||
NonNegativeLengthOrNumber, NumberOrPercentage, OutlineStyle,
|
NonNegativeLengthOrNumber, NumberOrPercentage, OutlineStyle,
|
||||||
};
|
};
|
||||||
use style::values::generics::rect::Rect;
|
use style::values::generics::rect::Rect;
|
||||||
|
@ -44,11 +44,12 @@ use crate::context::LayoutContext;
|
||||||
use crate::display_list::conversions::ToWebRender;
|
use crate::display_list::conversions::ToWebRender;
|
||||||
use crate::display_list::stacking_context::StackingContextSection;
|
use crate::display_list::stacking_context::StackingContextSection;
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag, TextFragment,
|
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag,
|
||||||
|
TextFragment,
|
||||||
};
|
};
|
||||||
use crate::geom::{LengthPercentageOrAuto, PhysicalPoint, PhysicalRect};
|
use crate::geom::{LengthPercentageOrAuto, PhysicalPoint, PhysicalRect};
|
||||||
use crate::replaced::NaturalSizes;
|
use crate::replaced::NaturalSizes;
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::{BorderStyleColor, ComputedValuesExt};
|
||||||
|
|
||||||
mod background;
|
mod background;
|
||||||
mod clip_path;
|
mod clip_path;
|
||||||
|
@ -863,10 +864,10 @@ impl<'a> BuilderForBoxFragment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_border_side(&mut self, style: BorderStyle, color: Color) -> wr::BorderSide {
|
fn build_border_side(&mut self, style_color: BorderStyleColor) -> wr::BorderSide {
|
||||||
wr::BorderSide {
|
wr::BorderSide {
|
||||||
color: rgba(self.fragment.style.resolve_color(color)),
|
color: rgba(self.fragment.style.resolve_color(style_color.color)),
|
||||||
style: match style {
|
style: match style_color.style {
|
||||||
BorderStyle::None => wr::BorderStyle::None,
|
BorderStyle::None => wr::BorderStyle::None,
|
||||||
BorderStyle::Solid => wr::BorderStyle::Solid,
|
BorderStyle::Solid => wr::BorderStyle::Solid,
|
||||||
BorderStyle::Double => wr::BorderStyle::Double,
|
BorderStyle::Double => wr::BorderStyle::Double,
|
||||||
|
@ -895,16 +896,17 @@ impl<'a> BuilderForBoxFragment<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let style_color = match &self.fragment.detailed_layout_info {
|
||||||
|
Some(SpecificLayoutInfo::TableOrTableCell(table_info)) => {
|
||||||
|
table_info.border_style_color.clone()
|
||||||
|
},
|
||||||
|
_ => BorderStyleColor::from_border(border),
|
||||||
|
};
|
||||||
let details = wr::BorderDetails::Normal(wr::NormalBorder {
|
let details = wr::BorderDetails::Normal(wr::NormalBorder {
|
||||||
top: self.build_border_side(border.border_top_style, border.border_top_color.clone()),
|
top: self.build_border_side(style_color.top),
|
||||||
right: self
|
right: self.build_border_side(style_color.right),
|
||||||
.build_border_side(border.border_right_style, border.border_right_color.clone()),
|
bottom: self.build_border_side(style_color.bottom),
|
||||||
bottom: self.build_border_side(
|
left: self.build_border_side(style_color.left),
|
||||||
border.border_bottom_style,
|
|
||||||
border.border_bottom_color.clone(),
|
|
||||||
),
|
|
||||||
left: self
|
|
||||||
.build_border_side(border.border_left_style, border.border_left_color.clone()),
|
|
||||||
radius: self.border_radius,
|
radius: self.border_radius,
|
||||||
do_aa: true,
|
do_aa: true,
|
||||||
});
|
});
|
||||||
|
@ -1028,7 +1030,10 @@ impl<'a> BuilderForBoxFragment<'a> {
|
||||||
OutlineStyle::Auto => BorderStyle::Solid,
|
OutlineStyle::Auto => BorderStyle::Solid,
|
||||||
OutlineStyle::BorderStyle(s) => s,
|
OutlineStyle::BorderStyle(s) => s,
|
||||||
};
|
};
|
||||||
let side = self.build_border_side(style, outline.outline_color.clone());
|
let side = self.build_border_side(BorderStyleColor {
|
||||||
|
style,
|
||||||
|
color: outline.outline_color.clone(),
|
||||||
|
});
|
||||||
let details = wr::BorderDetails::Normal(wr::NormalBorder {
|
let details = wr::BorderDetails::Normal(wr::NormalBorder {
|
||||||
top: side,
|
top: side,
|
||||||
right: side,
|
right: side,
|
||||||
|
|
|
@ -20,6 +20,7 @@ use crate::geom::{
|
||||||
AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical,
|
AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical,
|
||||||
};
|
};
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
use crate::table::SpecificTableOrTableCellInfo;
|
||||||
use crate::taffy::SpecificTaffyGridInfo;
|
use crate::taffy::SpecificTaffyGridInfo;
|
||||||
|
|
||||||
/// Describes how a [`BoxFragment`] paints its background.
|
/// Describes how a [`BoxFragment`] paints its background.
|
||||||
|
@ -43,6 +44,7 @@ pub(crate) struct ExtraBackground {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum SpecificLayoutInfo {
|
pub(crate) enum SpecificLayoutInfo {
|
||||||
Grid(Box<SpecificTaffyGridInfo>),
|
Grid(Box<SpecificTaffyGridInfo>),
|
||||||
|
TableOrTableCell(Box<SpecificTableOrTableCellInfo>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
|
@ -13,11 +13,12 @@ use style::logical_geometry::{Direction as AxisDirection, WritingMode};
|
||||||
use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity;
|
use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity;
|
||||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||||
use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
|
use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
|
||||||
|
use style::properties::style_structs::Border;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::servo::selector_parser::PseudoElement;
|
use style::servo::selector_parser::PseudoElement;
|
||||||
use style::values::computed::basic_shape::ClipPath;
|
use style::values::computed::basic_shape::ClipPath;
|
||||||
use style::values::computed::image::Image as ComputedImageLayer;
|
use style::values::computed::image::Image as ComputedImageLayer;
|
||||||
use style::values::computed::{AlignItems, BorderStyle, Inset, LengthPercentage, Margin};
|
use style::values::computed::{AlignItems, BorderStyle, Color, Inset, LengthPercentage, Margin};
|
||||||
use style::values::generics::box_::Perspective;
|
use style::values::generics::box_::Perspective;
|
||||||
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
|
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
|
||||||
use style::values::specified::align::AlignFlags;
|
use style::values::specified::align::AlignFlags;
|
||||||
|
@ -217,6 +218,36 @@ pub(crate) struct ContentBoxSizesAndPBMDeprecated {
|
||||||
pub depends_on_block_constraints: bool,
|
pub depends_on_block_constraints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub(crate) struct BorderStyleColor {
|
||||||
|
pub style: BorderStyle,
|
||||||
|
pub color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorderStyleColor {
|
||||||
|
pub(crate) fn new(style: BorderStyle, color: Color) -> Self {
|
||||||
|
Self { style, color }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_border(border: &Border) -> PhysicalSides<Self> {
|
||||||
|
PhysicalSides::<Self>::new(
|
||||||
|
Self::new(border.border_top_style, border.border_top_color.clone()),
|
||||||
|
Self::new(border.border_right_style, border.border_right_color.clone()),
|
||||||
|
Self::new(
|
||||||
|
border.border_bottom_style,
|
||||||
|
border.border_bottom_color.clone(),
|
||||||
|
),
|
||||||
|
Self::new(border.border_left_style, border.border_left_color.clone()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BorderStyleColor {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(BorderStyle::None, Color::TRANSPARENT_BLACK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) trait ComputedValuesExt {
|
pub(crate) trait ComputedValuesExt {
|
||||||
fn physical_box_offsets(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
|
fn physical_box_offsets(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
|
||||||
fn box_offsets(&self, writing_mode: WritingMode) -> LogicalSides<LengthPercentageOrAuto<'_>>;
|
fn box_offsets(&self, writing_mode: WritingMode) -> LogicalSides<LengthPercentageOrAuto<'_>>;
|
||||||
|
@ -279,8 +310,10 @@ pub(crate) trait ComputedValuesExt {
|
||||||
) -> PaddingBorderMargin;
|
) -> PaddingBorderMargin;
|
||||||
fn padding(&self, containing_block_writing_mode: WritingMode)
|
fn padding(&self, containing_block_writing_mode: WritingMode)
|
||||||
-> LogicalSides<LengthPercentage>;
|
-> LogicalSides<LengthPercentage>;
|
||||||
fn border_style(&self, containing_block_writing_mode: WritingMode)
|
fn border_style_color(
|
||||||
-> LogicalSides<BorderStyle>;
|
&self,
|
||||||
|
containing_block_writing_mode: WritingMode,
|
||||||
|
) -> LogicalSides<BorderStyleColor>;
|
||||||
fn border_width(&self, containing_block_writing_mode: WritingMode) -> LogicalSides<Au>;
|
fn border_width(&self, containing_block_writing_mode: WritingMode) -> LogicalSides<Au>;
|
||||||
fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
|
fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
|
||||||
fn margin(
|
fn margin(
|
||||||
|
@ -598,18 +631,12 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn border_style(
|
fn border_style_color(
|
||||||
&self,
|
&self,
|
||||||
containing_block_writing_mode: WritingMode,
|
containing_block_writing_mode: WritingMode,
|
||||||
) -> LogicalSides<BorderStyle> {
|
) -> LogicalSides<BorderStyleColor> {
|
||||||
let border = self.get_border();
|
|
||||||
LogicalSides::from_physical(
|
LogicalSides::from_physical(
|
||||||
&PhysicalSides::new(
|
&BorderStyleColor::from_border(self.get_border()),
|
||||||
border.border_top_style,
|
|
||||||
border.border_right_style,
|
|
||||||
border.border_bottom_style,
|
|
||||||
border.border_left_style,
|
|
||||||
),
|
|
||||||
containing_block_writing_mode,
|
containing_block_writing_mode,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
|
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
|
||||||
PositioningFragment,
|
PositioningFragment, SpecificLayoutInfo,
|
||||||
};
|
};
|
||||||
use crate::geom::{
|
use crate::geom::{
|
||||||
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
|
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
|
||||||
|
@ -37,12 +37,22 @@ use crate::geom::{
|
||||||
};
|
};
|
||||||
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
|
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
|
||||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||||
use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin};
|
use crate::style_ext::{BorderStyleColor, Clamp, ComputedValuesExt, PaddingBorderMargin};
|
||||||
use crate::table::TableSlotCoordinates;
|
use crate::table::{SpecificTableOrTableCellInfo, TableSlotCoordinates};
|
||||||
use crate::{
|
use crate::{
|
||||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
|
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn detailed_layout_info(
|
||||||
|
border_style_color: Option<PhysicalSides<BorderStyleColor>>,
|
||||||
|
) -> Option<SpecificLayoutInfo> {
|
||||||
|
Some(SpecificLayoutInfo::TableOrTableCell(Box::new(
|
||||||
|
SpecificTableOrTableCellInfo {
|
||||||
|
border_style_color: border_style_color?,
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
/// A result of a final or speculative layout of a single cell in
|
/// 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
|
/// the table. Note that this is only done for slots that are not
|
||||||
/// covered by spans or empty.
|
/// covered by spans or empty.
|
||||||
|
@ -50,6 +60,7 @@ struct CellLayout {
|
||||||
layout: IndependentLayout,
|
layout: IndependentLayout,
|
||||||
padding: LogicalSides<Au>,
|
padding: LogicalSides<Au>,
|
||||||
border: LogicalSides<Au>,
|
border: LogicalSides<Au>,
|
||||||
|
detailed_layout_info: Option<SpecificLayoutInfo>,
|
||||||
positioning_context: PositioningContext,
|
positioning_context: PositioningContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,31 +108,25 @@ struct ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A calculated collapsed border.
|
/// A calculated collapsed border.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
struct CollapsedBorder {
|
struct CollapsedBorder {
|
||||||
style: BorderStyle,
|
style_color: BorderStyleColor,
|
||||||
width: Au,
|
width: Au,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CollapsedBorder {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new(BorderStyle::None, Au::zero())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CollapsedBorder {
|
impl CollapsedBorder {
|
||||||
fn new(style: BorderStyle, width: Au) -> Self {
|
fn new(style_color: BorderStyleColor, width: Au) -> Self {
|
||||||
Self { style, width }
|
Self { style_color, width }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_style(style: &ComputedValues, writing_mode: WritingMode) -> LogicalSides<Self> {
|
fn from_style(style: &ComputedValues, writing_mode: WritingMode) -> LogicalSides<Self> {
|
||||||
let border_style = style.border_style(writing_mode);
|
let border_style_color = style.border_style_color(writing_mode);
|
||||||
let border_width = style.border_width(writing_mode);
|
let border_width = style.border_width(writing_mode);
|
||||||
LogicalSides {
|
LogicalSides {
|
||||||
inline_start: Self::new(border_style.inline_start, border_width.inline_start),
|
inline_start: Self::new(border_style_color.inline_start, border_width.inline_start),
|
||||||
inline_end: Self::new(border_style.inline_end, border_width.inline_end),
|
inline_end: Self::new(border_style_color.inline_end, border_width.inline_end),
|
||||||
block_start: Self::new(border_style.block_start, border_width.block_start),
|
block_start: Self::new(border_style_color.block_start, border_width.block_start),
|
||||||
block_end: Self::new(border_style.block_end, border_width.block_end),
|
block_end: Self::new(border_style_color.block_end, border_width.block_end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +143,10 @@ impl CollapsedBorder {
|
||||||
/// > 2. … has the biggest border-width, once converted into css pixels
|
/// > 2. … has the biggest border-width, once converted into css pixels
|
||||||
/// > 3. … has the border-style which comes first in the following list:
|
/// > 3. … has the border-style which comes first in the following list:
|
||||||
/// > double, solid, dashed, dotted, ridge, outset, groove, inset, none
|
/// > double, solid, dashed, dotted, ridge, outset, groove, inset, none
|
||||||
impl Ord for CollapsedBorder {
|
impl PartialOrd for CollapsedBorder {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
let style_specificity = |border: &Self| match border.style {
|
let is_hidden = |border: &Self| border.style_color.style == BorderStyle::Hidden;
|
||||||
|
let style_specificity = |border: &Self| match border.style_color.style {
|
||||||
BorderStyle::None => 0,
|
BorderStyle::None => 0,
|
||||||
BorderStyle::Inset => 1,
|
BorderStyle::Inset => 1,
|
||||||
BorderStyle::Groove => 2,
|
BorderStyle::Groove => 2,
|
||||||
|
@ -152,17 +158,18 @@ impl Ord for CollapsedBorder {
|
||||||
BorderStyle::Double => 8,
|
BorderStyle::Double => 8,
|
||||||
BorderStyle::Hidden => 9,
|
BorderStyle::Hidden => 9,
|
||||||
};
|
};
|
||||||
((self.style == BorderStyle::Hidden).cmp(&(other.style == BorderStyle::Hidden)))
|
let candidate = (is_hidden(self).cmp(&is_hidden(other)))
|
||||||
.then_with(|| self.width.cmp(&other.width))
|
.then_with(|| self.width.cmp(&other.width))
|
||||||
.then_with(|| style_specificity(self).cmp(&style_specificity(other)))
|
.then_with(|| style_specificity(self).cmp(&style_specificity(other)));
|
||||||
|
if !candidate.is_eq() || self.style_color.color == other.style_color.color {
|
||||||
|
Some(candidate)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for CollapsedBorder {
|
impl Eq for CollapsedBorder {}
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The calculated collapsed borders.
|
/// The calculated collapsed borders.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -275,7 +282,10 @@ impl<'a> TableLayout<'a> {
|
||||||
cell,
|
cell,
|
||||||
TableSlotCoordinates::new(column_index, row_index),
|
TableSlotCoordinates::new(column_index, row_index),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| cell.base.style.border_width(writing_mode));
|
.map_or_else(
|
||||||
|
|| cell.base.style.border_width(writing_mode),
|
||||||
|
|(border, _)| border,
|
||||||
|
);
|
||||||
|
|
||||||
let padding_border_sums = LogicalVec2 {
|
let padding_border_sums = LogicalVec2 {
|
||||||
inline: padding.inline_sum() + border.inline_sum(),
|
inline: padding.inline_sum() + border.inline_sum(),
|
||||||
|
@ -1185,13 +1195,20 @@ impl<'a> TableLayout<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let coordinates = TableSlotCoordinates::new(column_index, row_index);
|
let coordinates = TableSlotCoordinates::new(column_index, row_index);
|
||||||
let border: LogicalSides<Au> = self
|
let (border, detailed_layout_info) =
|
||||||
.get_collapsed_borders_for_cell(cell, coordinates)
|
match self.get_collapsed_borders_for_cell(cell, coordinates) {
|
||||||
.unwrap_or_else(|| {
|
Some((border_width, border_style_color)) => {
|
||||||
cell.base
|
let border_style_color = border_style_color
|
||||||
.style
|
.to_physical(self.table.style.writing_mode);
|
||||||
.border_width(containing_block_for_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 padding: LogicalSides<Au> = cell
|
let padding: LogicalSides<Au> = cell
|
||||||
.base
|
.base
|
||||||
|
@ -1228,6 +1245,7 @@ impl<'a> TableLayout<'a> {
|
||||||
layout,
|
layout,
|
||||||
padding,
|
padding,
|
||||||
border,
|
border,
|
||||||
|
detailed_layout_info,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1852,6 +1870,21 @@ impl<'a> TableLayout<'a> {
|
||||||
assert_eq!(self.table.size.height, self.row_sizes.len());
|
assert_eq!(self.table.size.height, self.row_sizes.len());
|
||||||
assert_eq!(self.table.size.width, self.distributed_column_widths.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 detailed_layout_info = detailed_layout_info(border_style_color);
|
||||||
|
|
||||||
if self.table.size.width == 0 && self.table.size.height == 0 {
|
if self.table.size.width == 0 && self.table.size.height == 0 {
|
||||||
let content_rect = LogicalRect {
|
let content_rect = LogicalRect {
|
||||||
start_corner: LogicalVec2::zero(),
|
start_corner: LogicalVec2::zero(),
|
||||||
|
@ -1871,7 +1904,8 @@ impl<'a> TableLayout<'a> {
|
||||||
PhysicalSides::zero(),
|
PhysicalSides::zero(),
|
||||||
None, /* clearance */
|
None, /* clearance */
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
);
|
)
|
||||||
|
.with_detailed_layout_info(detailed_layout_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut table_fragments = Vec::new();
|
let mut table_fragments = Vec::new();
|
||||||
|
@ -1998,6 +2032,7 @@ impl<'a> TableLayout<'a> {
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
)
|
)
|
||||||
.with_baselines(baselines)
|
.with_baselines(baselines)
|
||||||
|
.with_detailed_layout_info(detailed_layout_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_row_collapsed(&self, row_index: usize) -> bool {
|
fn is_row_collapsed(&self, row_index: usize) -> bool {
|
||||||
|
@ -2232,39 +2267,43 @@ impl<'a> TableLayout<'a> {
|
||||||
&self,
|
&self,
|
||||||
cell: &TableSlotCell,
|
cell: &TableSlotCell,
|
||||||
coordinates: TableSlotCoordinates,
|
coordinates: TableSlotCoordinates,
|
||||||
) -> Option<LogicalSides<Au>> {
|
) -> Option<(LogicalSides<Au>, LogicalSides<BorderStyleColor>)> {
|
||||||
let collapsed_borders = self.collapsed_borders.as_ref()?;
|
let collapsed_borders = self.collapsed_borders.as_ref()?;
|
||||||
let end_x = coordinates.x + cell.colspan;
|
let end_x = coordinates.x + cell.colspan;
|
||||||
let end_y = coordinates.y + cell.rowspan;
|
let end_y = coordinates.y + cell.rowspan;
|
||||||
let mut result = LogicalSides {
|
let inline_start = &collapsed_borders.inline[coordinates.x];
|
||||||
inline_start: collapsed_borders.inline[coordinates.x].width,
|
let inline_end = &collapsed_borders.inline[end_x];
|
||||||
inline_end: collapsed_borders.inline[end_x].width,
|
let block_start = &collapsed_borders.block[coordinates.y];
|
||||||
block_start: collapsed_borders.block[coordinates.y].width,
|
let block_end = &collapsed_borders.block[end_y];
|
||||||
block_end: collapsed_borders.block[end_y].width,
|
let border_width = LogicalSides {
|
||||||
|
inline_start: if coordinates.x == 0 {
|
||||||
|
inline_start.width - self.pbm.border.inline_start
|
||||||
|
} else {
|
||||||
|
inline_start.width / 2
|
||||||
|
},
|
||||||
|
inline_end: if end_x == self.table.size.width {
|
||||||
|
inline_end.width - self.pbm.border.inline_end
|
||||||
|
} else {
|
||||||
|
inline_end.width / 2
|
||||||
|
},
|
||||||
|
block_start: if coordinates.y == 0 {
|
||||||
|
block_start.width - self.pbm.border.block_start
|
||||||
|
} else {
|
||||||
|
block_start.width / 2
|
||||||
|
},
|
||||||
|
block_end: if end_y == self.table.size.height {
|
||||||
|
block_end.width - self.pbm.border.block_end
|
||||||
|
} else {
|
||||||
|
block_end.width / 2
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
let border_style_color = LogicalSides {
|
||||||
if coordinates.x == 0 {
|
inline_start: inline_start.style_color.clone(),
|
||||||
result.inline_start -= self.pbm.border.inline_start;
|
inline_end: inline_end.style_color.clone(),
|
||||||
} else {
|
block_start: block_start.style_color.clone(),
|
||||||
result.inline_start /= 2;
|
block_end: block_end.style_color.clone(),
|
||||||
}
|
};
|
||||||
if coordinates.y == 0 {
|
Some((border_width, border_style_color))
|
||||||
result.block_start -= self.pbm.border.block_start;
|
|
||||||
} else {
|
|
||||||
result.block_start /= 2;
|
|
||||||
}
|
|
||||||
if end_x == self.table.size.width {
|
|
||||||
result.inline_end -= self.pbm.border.inline_end;
|
|
||||||
} else {
|
|
||||||
result.inline_end /= 2;
|
|
||||||
}
|
|
||||||
if end_y == self.table.size.height {
|
|
||||||
result.block_end -= self.pbm.border.block_end;
|
|
||||||
} else {
|
|
||||||
result.block_end /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2828,6 +2867,7 @@ impl TableSlotCell {
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
)
|
)
|
||||||
.with_baselines(layout.layout.baselines)
|
.with_baselines(layout.layout.baselines)
|
||||||
|
.with_detailed_layout_info(layout.detailed_layout_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,9 @@ use crate::cell::ArcRefCell;
|
||||||
use crate::flow::BlockContainer;
|
use crate::flow::BlockContainer;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
|
use crate::geom::PhysicalSides;
|
||||||
use crate::layout_box_base::LayoutBoxBase;
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
|
use crate::style_ext::BorderStyleColor;
|
||||||
|
|
||||||
pub type TableSize = Size2D<usize, UnknownUnit>;
|
pub type TableSize = Size2D<usize, UnknownUnit>;
|
||||||
|
|
||||||
|
@ -320,3 +322,10 @@ pub struct TableCaption {
|
||||||
/// The contents of this cell, with its own layout.
|
/// The contents of this cell, with its own layout.
|
||||||
context: ArcRefCell<IndependentFormattingContext>,
|
context: ArcRefCell<IndependentFormattingContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) struct SpecificTableOrTableCellInfo {
|
||||||
|
/// 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>,
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-color-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-color-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-color-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-color-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-color-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-width-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-width-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-width-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-width-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-bottom-width-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-color-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-left-width-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-color-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-right-width-applies-to-006.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-color-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-color-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-color-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-color-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-color-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-width-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-width-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-width-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-width-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-top-width-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[blocks-025.xht]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/CSS2/tables/border-collapse-dynamic-cell-002.xht.ini
vendored
Normal file
2
tests/wpt/meta/css/CSS2/tables/border-collapse-dynamic-cell-002.xht.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[border-collapse-dynamic-cell-002.xht]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[border-conflict-element-001a.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-conflict-element-001b.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-conflict-element-001c.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e01.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e02.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e03.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e04.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e05.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003e06.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003f01.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[fixed-table-layout-003f02.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-collapse-dynamic-oof.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-conflict-resolution.html]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/css-tables/collapsed-border-remove-cell.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-tables/collapsed-border-remove-cell.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[collapsed-border-remove-cell.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[border_collapse_row_a.html]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue