Commit bd10fad5 authored by Aleks Totic's avatar Aleks Totic Committed by Commit Bot

[TablesNG] Move HasNonCollapsedBorderDecoration to PhysicalFragment

HasNonCollapsedBorderDecoration is a LayoutObject flag used in painting.
If flag is set, fragment participates in BorderDecoration painting.

Setting this flag in a way compatible with LayoutNG was problematic:

In Legacy, flag got reset every time style changed, and manually
set in Legacy table layout.
Because collapsed_borders is a property of Table, Cell needed its
table to set the flag properly.
Table was not available to cell when SetStyle was initially called,
so flag had to be manually set in LayoutNGTableRow::AddChild.

This patch adds HasNonCollapsedBorderDecoration flag to
table cells. The flag has to be passed from LayoutNGTableRow
through ConstraintSpace.

Bug: 958381
Change-Id: I7800d0c918ff78139df6748bed8a95c64cb19395
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2473806
Commit-Queue: Aleks Totic <atotic@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818178}
parent eb218b02
...@@ -3222,9 +3222,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, ...@@ -3222,9 +3222,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// !Table()->ShouldCollapseBorders(). // !Table()->ShouldCollapseBorders().
bool HasNonCollapsedBorderDecoration() const { bool HasNonCollapsedBorderDecoration() const {
NOT_DESTROYED(); NOT_DESTROYED();
// We can only ensure this flag is up-to-date after PrePaint.
DCHECK_GE(GetDocument().Lifecycle().GetState(), DCHECK_GE(GetDocument().Lifecycle().GetState(),
DocumentLifecycle::kPrePaintClean); DocumentLifecycle::kInPerformLayout);
return bitfields_.HasNonCollapsedBorderDecoration(); return bitfields_.HasNonCollapsedBorderDecoration();
} }
void SetHasNonCollapsedBorderDecoration(bool b) { void SetHasNonCollapsedBorderDecoration(bool b) {
......
...@@ -868,6 +868,13 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout( ...@@ -868,6 +868,13 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
border_box_size.inline_size); border_box_size.inline_size);
container_builder_.SetFragmentsTotalBlockSize(border_box_size.block_size); container_builder_.SetFragmentsTotalBlockSize(border_box_size.block_size);
// At this point, we need to perform any final table-cell adjustments
// needed.
if (ConstraintSpace().IsTableCell()) {
container_builder_.SetHasCollapsedBorders(
ConstraintSpace().IsTableCellWithCollapsedBorders());
}
// If our BFC block-offset is still unknown, we check: // If our BFC block-offset is still unknown, we check:
// - If we have a non-zero block-size (margins don't collapse through us). // - If we have a non-zero block-size (margins don't collapse through us).
// - If we have a break token. (Even if we are self-collapsing we position // - If we have a break token. (Even if we are self-collapsing we position
......
...@@ -107,6 +107,9 @@ NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject( ...@@ -107,6 +107,9 @@ NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
builder.SetHideTableCellIfEmpty( builder.SetHideTableCellIfEmpty(
cell_style.EmptyCells() == EEmptyCells::kHide && cell_style.EmptyCells() == EEmptyCells::kHide &&
table_style.BorderCollapse() == EBorderCollapse::kSeparate); table_style.BorderCollapse() == EBorderCollapse::kSeparate);
builder.SetHasTableCellCollapsedBorder(
cell_block.Parent()->Parent()->Parent()->StyleRef().BorderCollapse() ==
EBorderCollapse::kCollapse);
} }
if (block.IsAtomicInlineLevel() || block.IsFlexItem() || block.IsGridItem() || if (block.IsAtomicInlineLevel() || block.IsFlexItem() || block.IsGridItem() ||
......
...@@ -320,6 +320,11 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -320,6 +320,11 @@ class CORE_EXPORT NGConstraintSpace final {
return HasRareData() ? rare_data_->IsTableCellHiddenForPaint() : false; return HasRareData() ? rare_data_->IsTableCellHiddenForPaint() : false;
} }
bool IsTableCellWithCollapsedBorders() const {
return HasRareData() ? rare_data_->IsTableCellWithCollapsedBorders()
: false;
}
const NGTableConstraintSpaceData* TableData() const { const NGTableConstraintSpaceData* TableData() const {
return HasRareData() ? rare_data_->TableData() : nullptr; return HasRareData() ? rare_data_->TableData() : nullptr;
} }
...@@ -970,6 +975,15 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -970,6 +975,15 @@ class CORE_EXPORT NGConstraintSpace final {
EnsureTableCellData()->is_hidden_for_paint = is_hidden_for_paint; EnsureTableCellData()->is_hidden_for_paint = is_hidden_for_paint;
} }
bool IsTableCellWithCollapsedBorders() const {
return data_union_type == kTableCellData &&
table_cell_data_.has_collapsed_border;
}
void SetIsTableCellWithCollapsedBorders(bool has_collapsed_border) {
EnsureTableCellData()->has_collapsed_border = has_collapsed_border;
}
void SetTableRowData( void SetTableRowData(
scoped_refptr<const NGTableConstraintSpaceData> table_data, scoped_refptr<const NGTableConstraintSpaceData> table_data,
wtf_size_t row_index) { wtf_size_t row_index) {
...@@ -1089,7 +1103,8 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -1089,7 +1103,8 @@ class CORE_EXPORT NGConstraintSpace final {
table_cell_alignment_baseline == table_cell_alignment_baseline ==
other.table_cell_alignment_baseline && other.table_cell_alignment_baseline &&
table_cell_column_index == other.table_cell_column_index && table_cell_column_index == other.table_cell_column_index &&
is_hidden_for_paint == other.is_hidden_for_paint; is_hidden_for_paint == other.is_hidden_for_paint &&
has_collapsed_border == other.has_collapsed_border;
} }
bool IsInitialForMaySkipLayout() const { bool IsInitialForMaySkipLayout() const {
...@@ -1098,7 +1113,7 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -1098,7 +1113,7 @@ class CORE_EXPORT NGConstraintSpace final {
table_cell_intrinsic_padding_block_end == LayoutUnit() && table_cell_intrinsic_padding_block_end == LayoutUnit() &&
table_cell_column_index == kNotFound && table_cell_column_index == kNotFound &&
table_cell_alignment_baseline == base::nullopt && table_cell_alignment_baseline == base::nullopt &&
!is_hidden_for_paint; !is_hidden_for_paint && !has_collapsed_border;
} }
NGBoxStrut table_cell_borders; NGBoxStrut table_cell_borders;
...@@ -1107,6 +1122,7 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -1107,6 +1122,7 @@ class CORE_EXPORT NGConstraintSpace final {
wtf_size_t table_cell_column_index = kNotFound; wtf_size_t table_cell_column_index = kNotFound;
base::Optional<LayoutUnit> table_cell_alignment_baseline; base::Optional<LayoutUnit> table_cell_alignment_baseline;
bool is_hidden_for_paint = false; bool is_hidden_for_paint = false;
bool has_collapsed_border = false;
}; };
struct TableRowData { struct TableRowData {
......
...@@ -331,6 +331,15 @@ class CORE_EXPORT NGConstraintSpaceBuilder final { ...@@ -331,6 +331,15 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
space_.EnsureRareData()->SetIsTableCellHiddenForPaint(is_hidden_for_paint); space_.EnsureRareData()->SetIsTableCellHiddenForPaint(is_hidden_for_paint);
} }
void SetHasTableCellCollapsedBorder(bool is_collapsed_border) {
#if DCHECK_IS_ON()
DCHECK(!is_table_cell_collapsed_border_set_);
is_table_cell_collapsed_border_set_ = true;
#endif
space_.EnsureRareData()->SetIsTableCellWithCollapsedBorders(
is_collapsed_border);
}
void SetTableCellChildLayoutMode( void SetTableCellChildLayoutMode(
NGTableCellChildLayoutMode table_cell_child_layout_mode) { NGTableCellChildLayoutMode table_cell_child_layout_mode) {
space_.bitfields_.table_cell_child_layout_mode = space_.bitfields_.table_cell_child_layout_mode =
...@@ -454,6 +463,7 @@ class CORE_EXPORT NGConstraintSpaceBuilder final { ...@@ -454,6 +463,7 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
bool is_table_cell_alignment_baseline_set_ = false; bool is_table_cell_alignment_baseline_set_ = false;
bool is_table_cell_column_index_set_ = false; bool is_table_cell_column_index_set_ = false;
bool is_table_cell_hidden_for_paint_set_ = false; bool is_table_cell_hidden_for_paint_set_ = false;
bool is_table_cell_collapsed_border_set_ = false;
bool is_custom_layout_data_set_ = false; bool is_custom_layout_data_set_ = false;
bool is_lines_until_clamp_set_ = false; bool is_lines_until_clamp_set_ = false;
bool is_table_row_data_set_ = false; bool is_table_row_data_set_ = false;
......
...@@ -51,6 +51,8 @@ class CORE_EXPORT NGFragmentBuilder { ...@@ -51,6 +51,8 @@ class CORE_EXPORT NGFragmentBuilder {
void SetIsHiddenForPaint(bool value) { is_hidden_for_paint_ = value; } void SetIsHiddenForPaint(bool value) { is_hidden_for_paint_ = value; }
void SetHasCollapsedBorders(bool value) { has_collapsed_borders_ = value; }
const LayoutObject* GetLayoutObject() const { return layout_object_; } const LayoutObject* GetLayoutObject() const { return layout_object_; }
protected: protected:
...@@ -80,7 +82,7 @@ class CORE_EXPORT NGFragmentBuilder { ...@@ -80,7 +82,7 @@ class CORE_EXPORT NGFragmentBuilder {
LayoutObject* layout_object_ = nullptr; LayoutObject* layout_object_ = nullptr;
scoped_refptr<NGBreakToken> break_token_; scoped_refptr<NGBreakToken> break_token_;
bool is_hidden_for_paint_ = false; bool is_hidden_for_paint_ = false;
bool has_collapsed_borders_ = false;
friend class NGPhysicalFragment; friend class NGPhysicalFragment;
}; };
......
...@@ -278,6 +278,7 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder, ...@@ -278,6 +278,7 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
is_fieldset_container_(false), is_fieldset_container_(false),
is_legacy_layout_root_(false), is_legacy_layout_root_(false),
is_painted_atomically_(false), is_painted_atomically_(false),
has_collapsed_borders_(builder->has_collapsed_borders_),
has_baseline_(false) { has_baseline_(false) {
CHECK(builder->layout_object_); CHECK(builder->layout_object_);
} }
...@@ -300,6 +301,7 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, ...@@ -300,6 +301,7 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
is_fieldset_container_(false), is_fieldset_container_(false),
is_legacy_layout_root_(false), is_legacy_layout_root_(false),
is_painted_atomically_(false), is_painted_atomically_(false),
has_collapsed_borders_(false),
has_baseline_(false), has_baseline_(false),
has_last_baseline_(false) { has_last_baseline_(false) {
CHECK(layout_object); CHECK(layout_object);
...@@ -341,6 +343,7 @@ NGPhysicalFragment::NGPhysicalFragment(const NGPhysicalFragment& other) ...@@ -341,6 +343,7 @@ NGPhysicalFragment::NGPhysicalFragment(const NGPhysicalFragment& other)
is_fieldset_container_(other.is_fieldset_container_), is_fieldset_container_(other.is_fieldset_container_),
is_legacy_layout_root_(other.is_legacy_layout_root_), is_legacy_layout_root_(other.is_legacy_layout_root_),
is_painted_atomically_(other.is_painted_atomically_), is_painted_atomically_(other.is_painted_atomically_),
has_collapsed_borders_(other.has_collapsed_borders_),
has_baseline_(other.has_baseline_), has_baseline_(other.has_baseline_),
has_last_baseline_(other.has_last_baseline_), has_last_baseline_(other.has_last_baseline_),
ink_overflow_computed_(other.ink_overflow_computed_) { ink_overflow_computed_(other.ink_overflow_computed_) {
......
...@@ -172,6 +172,9 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -172,6 +172,9 @@ class CORE_EXPORT NGPhysicalFragment
// Returns whether the fragment should be atomically painted. // Returns whether the fragment should be atomically painted.
bool IsPaintedAtomically() const { return is_painted_atomically_; } bool IsPaintedAtomically() const { return is_painted_atomically_; }
// Returns whether the fragment is a table part with collapsed borders.
bool HasCollapsedBorders() const { return has_collapsed_borders_; }
bool IsFormattingContextRoot() const { bool IsFormattingContextRoot() const {
return (IsBox() && BoxType() >= NGBoxType::kMinimumFormattingContextRoot) || return (IsBox() && BoxType() >= NGBoxType::kMinimumFormattingContextRoot) ||
IsLegacyLayoutRoot(); IsLegacyLayoutRoot();
...@@ -491,6 +494,7 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -491,6 +494,7 @@ class CORE_EXPORT NGPhysicalFragment
unsigned is_fieldset_container_ : 1; unsigned is_fieldset_container_ : 1;
unsigned is_legacy_layout_root_ : 1; unsigned is_legacy_layout_root_ : 1;
unsigned is_painted_atomically_ : 1; unsigned is_painted_atomically_ : 1;
unsigned has_collapsed_borders_ : 1;
unsigned has_baseline_ : 1; unsigned has_baseline_ : 1;
unsigned has_last_baseline_ : 1; unsigned has_last_baseline_ : 1;
......
...@@ -93,6 +93,7 @@ scoped_refptr<const NGLayoutResult> NGTableRowLayoutAlgorithm::Layout() { ...@@ -93,6 +93,7 @@ scoped_refptr<const NGLayoutResult> NGTableRowLayoutAlgorithm::Layout() {
builder.SetTableCellBorders(cell_data.border_box_borders); builder.SetTableCellBorders(cell_data.border_box_borders);
builder.SetTableCellAlignmentBaseline(row_baseline); builder.SetTableCellAlignmentBaseline(row_baseline);
builder.SetTableCellColumnIndex(start_column); builder.SetTableCellColumnIndex(start_column);
builder.SetHasTableCellCollapsedBorder(table_data.has_collapsed_borders);
builder.SetNeedsBaseline(true); builder.SetNeedsBaseline(true);
builder.SetIsTableCellHiddenForPaint( builder.SetIsTableCellHiddenForPaint(
table_data.column_locations[*cell_location_start_column].is_collapsed && table_data.column_locations[*cell_location_start_column].is_collapsed &&
......
...@@ -20,14 +20,19 @@ class BoxDecorationData { ...@@ -20,14 +20,19 @@ class BoxDecorationData {
public: public:
BoxDecorationData(const PaintInfo& paint_info, const LayoutBox& layout_box) BoxDecorationData(const PaintInfo& paint_info, const LayoutBox& layout_box)
: BoxDecorationData(paint_info, layout_box, layout_box.StyleRef()) {} : BoxDecorationData(paint_info,
layout_box,
layout_box.StyleRef(),
layout_box.HasNonCollapsedBorderDecoration()) {}
BoxDecorationData(const PaintInfo& paint_info, BoxDecorationData(const PaintInfo& paint_info,
const NGPhysicalFragment& fragment, const NGPhysicalFragment& fragment,
const ComputedStyle& style) const ComputedStyle& style)
: BoxDecorationData(paint_info, : BoxDecorationData(
ToLayoutBox(*fragment.GetLayoutObject()), paint_info,
style) {} ToLayoutBox(*fragment.GetLayoutObject()),
style,
!fragment.HasCollapsedBorders() && style.HasBorderDecoration()) {}
BoxDecorationData(const PaintInfo& paint_info, BoxDecorationData(const PaintInfo& paint_info,
const NGPhysicalFragment& fragment) const NGPhysicalFragment& fragment)
...@@ -70,7 +75,8 @@ class BoxDecorationData { ...@@ -70,7 +75,8 @@ class BoxDecorationData {
private: private:
BoxDecorationData(const PaintInfo& paint_info, BoxDecorationData(const PaintInfo& paint_info,
const LayoutBox& layout_box, const LayoutBox& layout_box,
const ComputedStyle& style) const ComputedStyle& style,
const bool has_non_collapsed_border_decoration)
: paint_info_(paint_info), : paint_info_(paint_info),
layout_box_(layout_box), layout_box_(layout_box),
style_(style), style_(style),
...@@ -78,7 +84,8 @@ class BoxDecorationData { ...@@ -78,7 +84,8 @@ class BoxDecorationData {
IsPaintingScrollingBackground(paint_info, layout_box)), IsPaintingScrollingBackground(paint_info, layout_box)),
has_appearance_(style.HasEffectiveAppearance()), has_appearance_(style.HasEffectiveAppearance()),
should_paint_background_(ComputeShouldPaintBackground()), should_paint_background_(ComputeShouldPaintBackground()),
should_paint_border_(ComputeShouldPaintBorder()), should_paint_border_(
ComputeShouldPaintBorder(has_non_collapsed_border_decoration)),
should_paint_shadow_(ComputeShouldPaintShadow()) {} should_paint_shadow_(ComputeShouldPaintShadow()) {}
bool ComputeShouldPaintBackground() const { bool ComputeShouldPaintBackground() const {
...@@ -92,10 +99,11 @@ class BoxDecorationData { ...@@ -92,10 +99,11 @@ class BoxDecorationData {
return true; return true;
} }
bool ComputeShouldPaintBorder() const { bool ComputeShouldPaintBorder(
bool has_non_collapsed_border_decoration) const {
if (is_painting_scrolling_background_) if (is_painting_scrolling_background_)
return false; return false;
return layout_box_.HasNonCollapsedBorderDecoration(); return has_non_collapsed_border_decoration;
} }
bool ComputeShouldPaintShadow() const { bool ComputeShouldPaintShadow() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment