Skip to content

Commit

Permalink
[TableFragmentation] Paint column backgrounds correctly when fragmented.
Browse files Browse the repository at this point in the history
This correctly calculates the columns-rect when fragmentation is
present. Instead of relying on the table-grid-rect - union the section
fragments of the table.

Typically this will be relatively fast, as tables typically only have
one fragment, and one section as a child of that fragment.

Bug: 1078927
Change-Id: I10c293ea0b5f307342efe83761fc4257b316848b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3632008
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001001}
  • Loading branch information
bfgeek authored and Chromium LUCI CQ committed May 9, 2022
1 parent f48a1cb commit e93a2f0
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 10 deletions.
53 changes: 43 additions & 10 deletions third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,47 @@ void ComputeEdgeJoints(const NGTableBorders& collapsed_borders,
}
}

// Computes the stitched columns-rect relative to the current fragment.
// The columns-rect is the union of all the sections in the table.
PhysicalRect ComputeColumnsRect(const NGPhysicalBoxFragment& fragment) {
const auto writing_direction = fragment.Style().GetWritingDirection();
LogicalRect columns_rect;
LayoutUnit stitched_block_size;
LayoutUnit fragment_block_offset;

bool is_first_section = true;
for (const NGPhysicalBoxFragment& walker :
To<LayoutBox>(fragment.GetLayoutObject())->PhysicalFragments()) {
if (&walker == &fragment)
fragment_block_offset = stitched_block_size;

WritingModeConverter converter(writing_direction, walker.Size());
for (const auto& child : walker.Children()) {
if (!child->IsTableNGSection())
continue;

LogicalRect section_rect =
converter.ToLogical({child.offset, child->Size()});
section_rect.offset.block_offset += stitched_block_size;

if (is_first_section) {
columns_rect = section_rect;
is_first_section = false;
} else {
columns_rect.UniteEvenIfEmpty(section_rect);
}
}

stitched_block_size += NGFragment(writing_direction, walker).BlockSize();
}

// Make the rect relative to the fragment we are currently painting.
columns_rect.offset.block_offset -= fragment_block_offset;

WritingModeConverter converter(writing_direction, fragment.Size());
return converter.ToPhysical(columns_rect);
}

// When painting background in a cell (for the cell or its ancestor table part),
// if any ancestor table part has a layer and the table collapses borders, the
// background is painted after the collapsed borders. We need to clip the
Expand Down Expand Up @@ -380,17 +421,9 @@ void NGTablePainter::PaintBoxDecorationBackground(
if (column_geometries_with_background.IsEmpty())
return;

const auto& style = fragment_.Style();
LogicalSize spacing = style.TableBorderSpacing();
NGBoxStrut spacing_strut(spacing.inline_size, spacing.inline_size,
spacing.block_size, spacing.block_size);

PhysicalRect columns_paint_rect = grid_paint_rect;
columns_paint_rect.Contract(
fragment_.Borders() + fragment_.Padding() +
spacing_strut.ConvertToPhysical(style.GetWritingDirection()));

// Paint <colgroup>/<col> backgrounds.
PhysicalRect columns_paint_rect = ComputeColumnsRect(fragment_);
columns_paint_rect.offset += paint_rect.offset;
for (const NGLink& child : fragment_.Children()) {
if (!child.fragment->IsTableNGSection())
continue;
Expand Down
2 changes: 2 additions & 0 deletions third_party/blink/web_tests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,7 @@ virtual/layout_ng_table_frag/external/wpt/css/css-break/table/break-before-expan
virtual/layout_ng_table_frag/external/wpt/css/css-break/table/break-before-table-cell.html [ Pass ]
virtual/layout_ng_table_frag/external/wpt/css/css-break/table/break-before-table-cell-child.html [ Pass ]
virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-cell-expansion-003.html [ Pass ]
virtual/layout_ng_table_frag/external/wpt/css/css-break/table/table-col-paint-htb-ltr.html [ Pass ]

### Tests failing with LayoutNGTableFragmentation enabled:
crbug.com/1295905 [ Mac11-arm64 ] virtual/layout_ng_table_frag/external/wpt/css/css-break/table/sections-and-captions-mixed-order.html [ Failure ]
Expand Down Expand Up @@ -3886,6 +3887,7 @@ crbug.com/1078927 external/wpt/css/css-break/table/break-before-expansion-002.ht
crbug.com/1078927 external/wpt/css/css-break/table/break-before-table-cell.html [ Failure ]
crbug.com/1078927 external/wpt/css/css-break/table/break-before-table-cell-child.html [ Failure ]
crbug.com/1078927 external/wpt/css/css-break/table/table-cell-expansion-003.html [ Failure ]
crbug.com/1078927 external/wpt/css/css-break/table/table-col-paint-htb-ltr.html [ Failure ]
crbug.com/1058792 external/wpt/css/css-break/transform-007.html [ Failure ]
crbug.com/1224888 external/wpt/css/css-break/transform-009.html [ Failure ]
crbug.com/1156312 external/wpt/css/css-break/widows-orphans-017.html [ Failure ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<style>
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<div style="position: relative; inline-size: 100%; block-size: 400px;">
<div style="position: absolute; inset-block-start: 0; inline-size: 100%; background: red; block-size: 50px;"></div>
<div class="pattern1" style="position: absolute; inset-block-start: 60px; inset-inline-start: 10px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div class="pattern2" style="position: absolute; inset-block-start: 60px; inset-inline-start: 55px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div style="position: absolute; inset-block-start: 170px; inline-size: 100%; block-size: 10px; background: white;"></div>
<div style="position: absolute; inset-block-end: 0; inline-size: 100%; background: red; block-size: 75px;"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<link rel="match" href="table-col-paint-htb-ltr-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#fragmentation">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#rendering">
<style>
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<table style="border-spacing: 10px; inline-size: 100%;">
<caption style="background: red; block-size: 50px;"></caption>
<col class="pattern1"></col>
<col class="pattern2"></col>
<tr style="block-size: 110px;">
<td></td>
<td></td>
</tr>
<tr style="block-size: 135px;">
<td></td>
<td></td>
</tr>
<caption style="caption-side: bottom; background: red; block-size: 75px;"></caption>
</table>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<style>
body {
writing-mode: vertical-lr;
direction: rtl;
}
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(to right, lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(to right, orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<div style="position: relative; inline-size: 100%; block-size: 400px;">
<div style="position: absolute; inset-block-start: 0; inline-size: 100%; background: red; block-size: 50px;"></div>
<div class="pattern1" style="position: absolute; inset-block-start: 60px; inset-inline-start: 10px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div class="pattern2" style="position: absolute; inset-block-start: 60px; inset-inline-start: 55px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div style="position: absolute; inset-block-start: 170px; inline-size: 100%; block-size: 10px; background: white;"></div>
<div style="position: absolute; inset-block-end: 0; inline-size: 100%; background: red; block-size: 75px;"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<link rel="match" href="table-col-paint-vlr-rtl-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#fragmentation">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#rendering">
<style>
body {
writing-mode: vertical-lr;
direction: rtl;
}
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(to right,lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(to right, orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<table style="border-spacing: 10px; inline-size: 100%;">
<caption style="background: red; block-size: 50px;"></caption>
<col class="pattern1"></col>
<col class="pattern2"></col>
<tr style="block-size: 110px;">
<td></td>
<td></td>
</tr>
<tr style="block-size: 135px;">
<td></td>
<td></td>
</tr>
<caption style="caption-side: bottom; background: red; block-size: 75px;"></caption>
</table>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<style>
body {
writing-mode: vertical-rl;
direction: rtl;
}
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(to left, lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(to left, orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<div style="position: relative; inline-size: 100%; block-size: 400px;">
<div style="position: absolute; inset-block-start: 0; inline-size: 100%; background: red; block-size: 50px;"></div>
<div class="pattern1" style="position: absolute; inset-block-start: 60px; inset-inline-start: 10px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div class="pattern2" style="position: absolute; inset-block-start: 60px; inset-inline-start: 55px; inline-size: calc(50% - 15px); block-size: 255px;"></div>
<div style="position: absolute; inset-block-start: 170px; inline-size: 100%; block-size: 10px; background: white;"></div>
<div style="position: absolute; inset-block-end: 0; inline-size: 100%; background: red; block-size: 75px;"></div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<link rel="match" href="table-col-paint-vrl-rtl-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#fragmentation">
<link rel="help" href="https://drafts.csswg.org/css-tables-3/#rendering">
<style>
body {
writing-mode: vertical-rl;
direction: rtl;
}
.multicol {
inline-size: 400px;
block-size: 100px;
columns: 4;
column-fill: auto;
gap: 0;
}
.pattern1 {
background: repeating-linear-gradient(to left,lime, lime 20px, blue 20px, blue 40px);
}
.pattern2 {
background: repeating-linear-gradient(to left, orange, orange 30px, dodgerblue 30px, dodgerblue 60px);
}
</style>
<div class="multicol">
<table style="border-spacing: 10px; inline-size: 100%;">
<caption style="background: red; block-size: 50px;"></caption>
<col class="pattern1"></col>
<col class="pattern2"></col>
<tr style="block-size: 110px;">
<td></td>
<td></td>
</tr>
<tr style="block-size: 135px;">
<td></td>
<td></td>
</tr>
<caption style="caption-side: bottom; background: red; block-size: 75px;"></caption>
</table>
</div>

0 comments on commit e93a2f0

Please sign in to comment.