Commit 4c36a7b2 authored by Aleks Totic's avatar Aleks Totic Committed by Commit Bot

[TablesNG] Box order for painting

Use box order to resolve intersection edge precedence.

Makes 9 additional tests pass:

css2.1/20110323/border-conflict-element-001d.htm
external/wpt/css/CSS2/tables/border-conflict-element-001d.xht
external/wpt/css/CSS2/tables/border-conflict-element-001e.xht
fast/css/table-rules-attribute-groups-with-frame.html
fast/table/colgroup-spanning-groups-rules.html
fast/table/border-collapsing/002-vertical.html
fast/table/border-collapsing/002.html
tables/mozilla/core/table_rules.html
tables/mozilla/marvin/x_table_rules_groups.xml

Bug: 958381
Change-Id: I53f87d716aada00edec5f06129842fc1fc10eb68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2519882
Commit-Queue: Aleks Totic <atotic@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824701}
parent 09dd36ac
......@@ -120,8 +120,8 @@ class ColBordersMarker {
for (wtf_size_t i = 0; i < span; ++i) {
wtf_size_t current_column_index = start_column_index + i;
borders.MergeBorders(0, current_column_index, table_row_count, 1,
&column.Style(), NGTableBorders::EdgeSource::kColumn,
table_writing_direction);
column.Style(), NGTableBorders::EdgeSource::kColumn,
box_order, table_writing_direction);
}
}
void EnterColgroup(const NGLayoutInputNode& colgroup,
......@@ -131,13 +131,16 @@ class ColBordersMarker {
wtf_size_t span,
bool has_children) {}
ColBordersMarker(wtf_size_t table_row_count,
wtf_size_t box_order,
WritingDirectionMode table_writing_direction,
NGTableBorders& borders)
: table_row_count(table_row_count),
box_order(box_order),
table_writing_direction(table_writing_direction),
borders(borders) {}
wtf_size_t table_row_count;
WritingDirectionMode table_writing_direction;
const wtf_size_t table_row_count;
const wtf_size_t box_order;
const WritingDirectionMode table_writing_direction;
NGTableBorders& borders;
};
......@@ -155,17 +158,20 @@ class ColgroupBordersMarker {
wtf_size_t span,
bool has_children) {
borders.MergeBorders(0, start_column_index, table_row_count, span,
&colgroup.Style(), NGTableBorders::EdgeSource::kColumn,
table_writing_direction);
colgroup.Style(), NGTableBorders::EdgeSource::kColumn,
box_order, table_writing_direction);
}
ColgroupBordersMarker(wtf_size_t table_row_count,
wtf_size_t box_order,
WritingDirectionMode table_writing_direction,
NGTableBorders& borders)
: table_row_count(table_row_count),
box_order(box_order),
table_writing_direction(table_writing_direction),
borders(borders) {}
wtf_size_t table_row_count;
WritingDirectionMode table_writing_direction;
const wtf_size_t table_row_count;
const wtf_size_t box_order;
const WritingDirectionMode table_writing_direction;
NGTableBorders& borders;
};
......@@ -188,6 +194,7 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
bool hide_empty_cells = table_style.EmptyCells() == EEmptyCells::kHide;
WritingDirectionMode table_writing_direction =
table.Style().GetWritingDirection();
wtf_size_t box_order = 0;
wtf_size_t table_column_count = 0;
wtf_size_t table_row_index = 0;
......@@ -220,8 +227,9 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
if (!found_multispan_cells) {
table_borders->MergeBorders(
table_row_index, tabulator.CurrentColumn(),
cell.TableCellRowspan(), cell_colspan, &cell.Style(),
NGTableBorders::EdgeSource::kCell, table_writing_direction);
cell.TableCellRowspan(), cell_colspan, cell.Style(),
NGTableBorders::EdgeSource::kCell, ++box_order,
table_writing_direction);
}
tabulator.ProcessCell(cell);
}
......@@ -254,9 +262,9 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
}
table_borders->MergeBorders(
table_row_index, tabulator.CurrentColumn(),
cell.TableCellRowspan(), cell.TableCellColspan(), &cell.Style(),
NGTableBorders::EdgeSource::kCell, table_writing_direction,
section_index);
cell.TableCellRowspan(), cell.TableCellColspan(), cell.Style(),
NGTableBorders::EdgeSource::kCell, ++box_order,
table_writing_direction, section_index);
tabulator.ProcessCell(cell);
}
tabulator.EndRow();
......@@ -271,9 +279,9 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
for (NGBlockNode section : grouped_children) {
for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row;
row = To<NGBlockNode>(row.NextSibling())) {
table_borders->MergeBorders(
table_row_index, 0, 1, table_column_count, &row.Style(),
NGTableBorders::EdgeSource::kRow, table_writing_direction);
table_borders->MergeBorders(table_row_index, 0, 1, table_column_count,
row.Style(), NGTableBorders::EdgeSource::kRow,
++box_order, table_writing_direction);
++table_row_index;
}
}
......@@ -287,7 +295,7 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
table_borders->GetSection(section_index);
table_borders->MergeBorders(
section_info.start_row, 0, section_info.row_count, table_column_count,
&section.Style(), NGTableBorders::EdgeSource::kSection,
section.Style(), NGTableBorders::EdgeSource::kSection, ++box_order,
table_writing_direction);
++section_index;
}
......@@ -295,21 +303,23 @@ scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
// Mark column borders.
// COL borders have precedence over COLGROUP borders.
// We have to traverse COL first, then COLGROUP.
ColBordersMarker col_borders_marker(table_row_count, table_writing_direction,
ColBordersMarker col_borders_marker(table_row_count, ++box_order,
table_writing_direction,
*table_borders.get());
VisitLayoutNGTableColumn(
const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
table_column_count, &col_borders_marker);
ColgroupBordersMarker colgroup_borders_marker(
table_row_count, table_writing_direction, *table_borders.get());
ColgroupBordersMarker colgroup_borders_marker(table_row_count, ++box_order,
table_writing_direction,
*table_borders.get());
VisitLayoutNGTableColumn(
const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
table_column_count, &colgroup_borders_marker);
// Mark table borders.
table_borders->MergeBorders(0, 0, table_row_count, table_column_count,
&table_style, NGTableBorders::EdgeSource::kTable,
table_writing_direction);
table_style, NGTableBorders::EdgeSource::kTable,
++box_order, table_writing_direction);
table_borders->ComputeCollapsedTableBorderPadding(table_row_count,
table_column_count);
......@@ -492,8 +502,9 @@ void NGTableBorders::MergeBorders(wtf_size_t cell_start_row,
wtf_size_t cell_start_column,
wtf_size_t rowspan,
wtf_size_t colspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
EdgeSource source,
const wtf_size_t box_order,
WritingDirectionMode table_writing_direction,
wtf_size_t section_index) {
DCHECK(is_collapsed_);
......@@ -514,9 +525,9 @@ void NGTableBorders::MergeBorders(wtf_size_t cell_start_row,
EnsureCellRowFits(cell_start_row + clamped_rowspan - 1);
} else {
PhysicalToLogical<EBorderStyle> border_style(
table_writing_direction, source_style->BorderTopStyle(),
source_style->BorderRightStyle(), source_style->BorderBottomStyle(),
source_style->BorderLeftStyle());
table_writing_direction, source_style.BorderTopStyle(),
source_style.BorderRightStyle(), source_style.BorderBottomStyle(),
source_style.BorderLeftStyle());
if (border_style.InlineStart() == EBorderStyle::kNone &&
border_style.InlineEnd() == EBorderStyle::kNone &&
border_style.BlockStart() == EBorderStyle::kNone &&
......@@ -540,19 +551,19 @@ void NGTableBorders::MergeBorders(wtf_size_t cell_start_row,
}
}
MergeRowAxisBorder(cell_start_row, cell_start_column, clamped_colspan,
source_style,
source_style, box_order,
LogicalEdgeToPhysical(LogicalEdgeSide::kBlockStart,
table_writing_direction));
MergeRowAxisBorder(cell_start_row + clamped_rowspan, cell_start_column,
clamped_colspan, source_style,
clamped_colspan, source_style, box_order,
LogicalEdgeToPhysical(LogicalEdgeSide::kBlockEnd,
table_writing_direction));
MergeColumnAxisBorder(cell_start_row, cell_start_column, clamped_rowspan,
source_style,
source_style, box_order,
LogicalEdgeToPhysical(LogicalEdgeSide::kInlineStart,
table_writing_direction));
MergeColumnAxisBorder(cell_start_row, cell_start_column + clamped_colspan,
clamped_rowspan, source_style,
clamped_rowspan, source_style, box_order,
LogicalEdgeToPhysical(LogicalEdgeSide::kInlineEnd,
table_writing_direction));
if (mark_inner_borders) {
......@@ -564,12 +575,13 @@ void NGTableBorders::MergeBorders(wtf_size_t cell_start_row,
void NGTableBorders::MergeRowAxisBorder(wtf_size_t start_row,
wtf_size_t start_column,
wtf_size_t colspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
const wtf_size_t box_order,
EdgeSide physical_side) {
EBorderStyle source_border_style = BorderStyle(source_style, physical_side);
EBorderStyle source_border_style = BorderStyle(&source_style, physical_side);
if (source_border_style == EBorderStyle::kNone)
return;
LayoutUnit source_border_width = BorderWidth(source_style, physical_side);
LayoutUnit source_border_width = BorderWidth(&source_style, physical_side);
wtf_size_t start_edge = edges_per_row_ * start_row + start_column * 2 + 1;
wtf_size_t end_edge = start_edge + colspan * 2;
for (wtf_size_t current_edge = start_edge; current_edge < end_edge;
......@@ -577,8 +589,9 @@ void NGTableBorders::MergeRowAxisBorder(wtf_size_t start_row,
// https://www.w3.org/TR/css-tables-3/#border-specificity
if (IsSourceMoreSpecificThanEdge(source_border_style, source_border_width,
edges_[current_edge])) {
edges_[current_edge].style = source_style;
edges_[current_edge].style = &source_style;
edges_[current_edge].edge_side = physical_side;
edges_[current_edge].box_order = box_order;
}
}
}
......@@ -586,12 +599,13 @@ void NGTableBorders::MergeRowAxisBorder(wtf_size_t start_row,
void NGTableBorders::MergeColumnAxisBorder(wtf_size_t start_row,
wtf_size_t start_column,
wtf_size_t rowspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
const wtf_size_t box_order,
EdgeSide physical_side) {
EBorderStyle source_border_style = BorderStyle(source_style, physical_side);
EBorderStyle source_border_style = BorderStyle(&source_style, physical_side);
if (source_border_style == EBorderStyle::kNone)
return;
LayoutUnit source_border_width = BorderWidth(source_style, physical_side);
LayoutUnit source_border_width = BorderWidth(&source_style, physical_side);
wtf_size_t start_edge = edges_per_row_ * start_row + start_column * 2;
wtf_size_t end_edge = start_edge + (rowspan * edges_per_row_);
for (wtf_size_t current_edge = start_edge; current_edge < end_edge;
......@@ -599,8 +613,9 @@ void NGTableBorders::MergeColumnAxisBorder(wtf_size_t start_row,
// https://www.w3.org/TR/css-tables-3/#border-specificity
if (IsSourceMoreSpecificThanEdge(source_border_style, source_border_width,
edges_[current_edge])) {
edges_[current_edge].style = source_style;
edges_[current_edge].style = &source_style;
edges_[current_edge].edge_side = physical_side;
edges_[current_edge].box_order = box_order;
}
}
}
......
......@@ -80,6 +80,11 @@ class NGTableBorders : public RefCounted<NGTableBorders> {
struct Edge {
scoped_refptr<const ComputedStyle> style;
EdgeSide edge_side;
// Box order is used to compute edge painting precedence.
// Lower box order has precedence.
// The order value is defined as "box visited index" while
// computing collapsed edges.
wtf_size_t box_order;
};
static LayoutUnit BorderWidth(const ComputedStyle* style,
......@@ -172,6 +177,10 @@ class NGTableBorders : public RefCounted<NGTableBorders> {
edges_[edge_index].edge_side);
}
wtf_size_t BoxOrder(wtf_size_t edge_index) const {
return edges_[edge_index].box_order;
}
using Edges = Vector<Edge>;
struct Section {
......@@ -219,8 +228,9 @@ class NGTableBorders : public RefCounted<NGTableBorders> {
wtf_size_t start_column,
wtf_size_t rowspan,
wtf_size_t colspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
EdgeSource source,
wtf_size_t box_order,
WritingDirectionMode table_writing_direction,
wtf_size_t section_index = kNotFound);
......@@ -297,13 +307,15 @@ class NGTableBorders : public RefCounted<NGTableBorders> {
void MergeRowAxisBorder(wtf_size_t start_row,
wtf_size_t start_column,
wtf_size_t colspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
wtf_size_t box_order,
EdgeSide side);
void MergeColumnAxisBorder(wtf_size_t start_row,
wtf_size_t start_column,
wtf_size_t rowspan,
const ComputedStyle* source_style,
const ComputedStyle& source_style,
wtf_size_t box_order,
EdgeSide side);
void MarkInnerBordersAsDoNotFill(wtf_size_t start_row,
......
......@@ -69,6 +69,16 @@ class NGTableCollapsedEdge {
Color BorderColor() const { return borders_.BorderColor(edge_index_); }
int CompareBoxOrder(wtf_size_t other_edge_index) const {
wtf_size_t box_order = borders_.BoxOrder(edge_index_);
wtf_size_t other_box_order = borders_.BoxOrder(other_edge_index);
if (box_order < other_box_order)
return 1;
if (box_order > other_box_order)
return -1;
return 0;
}
bool IsInlineAxis() const {
DCHECK(Exists());
DCHECK_NE(edge_index_, UINT_MAX);
......@@ -103,7 +113,7 @@ class NGTableCollapsedEdge {
// Paint border style comparison for paint has different
// rules than for winning edge border (hidden does not win).
if (lhs.border_style_ == rhs.border_style_)
return 0;
return lhs.CompareBoxOrder(rhs.edge_index_);
if (rhs.border_style_ == EBorderStyle::kHidden)
return 1;
if (lhs.border_style_ == EBorderStyle::kHidden)
......
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