Skip to content

Commit

Permalink
vaev-layout: fix table layer interaction
Browse files Browse the repository at this point in the history
Before: table layers defined by rows/cols/groups were treated as boxes and
background interaction was in function of overlapping boxes.
This was wrong though because the background color of rows/cols/groups should
be only for the cells, not the whole rectangle defined by the cells (the said
boxes).

Now: background defined by rows/cols/groups are added to the cell style, what
will prevent the background printing on wrong places and the override of calling
layout for rows/cols/groups (what was also 'incorrect').

Note that, in borders collapse, rows/cols/groups can have borders and the same
strategy will need to be applied.
  • Loading branch information
pauloamed committed Nov 21, 2024
1 parent 0d5c81c commit 094bf81
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 82 deletions.
114 changes: 34 additions & 80 deletions src/vaev-layout/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,12 +796,34 @@ struct TableFormatingContext {
}
}

struct AxisHelper {
Opt<usize> groupIdx = NONE;
Opt<usize> axisIdx = NONE;
};

Vec<AxisHelper> buildAxisHelper(Vec<TableAxis> const &axes, Vec<TableGroup> const &groups, usize len) {
Vec<AxisHelper> helper{Buf<AxisHelper>::init(len)};
for (usize groupIdx = 0; groupIdx < groups.len(); groupIdx++) {
for (usize i = groups[groupIdx].start; i <= groups[groupIdx].end; ++i)
helper[i].groupIdx = groupIdx;
}
for (usize axisIdx = 0; axisIdx < axes.len(); axisIdx++) {
for (usize i = axes[axisIdx].start; i <= axes[axisIdx].end; ++i)
helper[i].axisIdx = axisIdx;
}
return helper;
};

Vec2Px tableBoxSize;
Vec<AxisHelper> rowHelper, colHelper;

void build(Tree &tree, Input input) {
buildHTMLTable();
buildBordersGrid(tree);

rowHelper = buildAxisHelper(rows, rowGroups, grid.size.y);
colHelper = buildAxisHelper(cols, colGroups, grid.size.x);

// NOTE: When "table-layout: fixed" is set but "width: auto", the specs suggest
// that the UA can use the fixed layout after computing the width
// (see https://www.w3.org/TR/CSS22/visudet.html#blockwidth).
Expand Down Expand Up @@ -833,7 +855,6 @@ struct TableFormatingContext {
}

void runTableBox(Tree &tree, Input input, Px &currPositionY) {
// TODO: this should be rewritten having a row index into account instead of cell/row/col(group)
PrefixSum<Px> colWidthPref{colWidth}, rowHeightPref{rowHeight};
Px currPositionX{input.position.x};

Expand All @@ -853,83 +874,6 @@ struct TableFormatingContext {

currPositionX += boxBorder.start + spacing.x;
currPositionY += boxBorder.top + spacing.y;

// column groups
for (auto &group : colGroups) {
layout(
tree,
group.el,
{
.commit = Commit::YES,
.knownSize = {
colWidthPref.query(group.start, group.end),
tableBoxSize.y,
},
.position = {
currPositionX + colWidthPref.query(0, group.start - 1),
currPositionY,
},
}
);
}

// columns
for (auto &col : cols) {
layout(
tree,
col.el,
{
.commit = Commit::YES,
.knownSize = {
colWidthPref.query(col.start, col.end),
tableBoxSize.y,
},
.position = {
currPositionX,
currPositionY + colWidthPref.query(0, col.start - 1),
},
}
);
}

// row groups
for (auto &group : rowGroups) {
layout(
tree,
group.el,
{
.commit = Commit::YES,
.knownSize = {
tableBoxSize.x,
rowHeightPref.query(group.start, group.end),
},
.position = {
currPositionX,
currPositionY + rowHeightPref.query(0, group.start - 1),
},
}
);
}

// rows
for (auto &row : rows) {
layout(
tree,
row.el,
{
.commit = Commit::YES,
.knownSize = {
tableBoxSize.x,
rowHeightPref.query(row.start, row.end),
},
.position = {
currPositionX,
currPositionY + rowHeightPref.query(0, row.start - 1),
},
}
);
}

// cells
for (usize i = 0; i < grid.size.y; currPositionY += rowHeight[i] + spacing.y, i++) {
Px innnerCurrPositionX = Px{currPositionX};
Expand All @@ -942,14 +886,24 @@ struct TableFormatingContext {
auto colSpan = cell.box->attrs.colSpan;
auto rowSpan = cell.box->attrs.rowSpan;

// https://www.w3.org/TR/CSS22/tables.html#table-layers
if (rowHelper[i].axisIdx)
cell.box->style->backgrounds.pushFront(rows[rowHelper[i].axisIdx.unwrap()].el.style->backgrounds);
if (rowHelper[i].groupIdx)
cell.box->style->backgrounds.pushFront(rowGroups[rowHelper[i].groupIdx.unwrap()].el.style->backgrounds);
if (colHelper[j].axisIdx)
cell.box->style->backgrounds.pushFront(cols[colHelper[j].axisIdx.unwrap()].el.style->backgrounds);
if (colHelper[j].groupIdx)
cell.box->style->backgrounds.pushFront(colGroups[colHelper[j].groupIdx.unwrap()].el.style->backgrounds);

// TODO: In CSS 2.2, the height of a cell box is the minimum
// height required by the content.
// The table cell's 'height' property can influence
// the height of the row (see above), but it does not
// increase the height of the cell box.
//
// (See https://www.w3.org/TR/CSS22/tables.html#height-layout)
auto cellOutput = layout(
layout(
tree,
*cell.box,
{
Expand All @@ -958,7 +912,7 @@ struct TableFormatingContext {
colWidthPref.query(j, j + colSpan - 1) + spacing.x * Px{colSpan - 1},
rowHeightPref.query(i, i + rowSpan - 1) + spacing.y * Px{rowSpan - 1}
},
.position{innnerCurrPositionX, currPositionY},
.position = {innnerCurrPositionX, currPositionY},
}
);
};
Expand Down
95 changes: 93 additions & 2 deletions tests/css/display-table.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -1059,15 +1059,15 @@
}

.yellow {
background-color: rgba(255, 255, 0, 0.37);
background-color: rgba(255, 255, 0, 0.445);
}

.gray {
background-color: rgba(197, 197, 178, 0.37);
}

.orange {
background-color: rgba(231, 134, 8, 0.603);
background-color: rgba(231, 134, 8, 0.253);
}

.purple {
Expand Down Expand Up @@ -1274,6 +1274,97 @@

</test>

<test name="table: fixed + background + spacing" size="320">
<container>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">

<head>
<style>
/* BEGIN: reset chrome's added style */
body {
margin: 0;
}

th,
td {
padding: 0;
border: 0;
}

/* END: reset chrome's added style */

table {
border-spacing: 10px 20px;
}

.color1 {
background-color: aqua;
}

.color2 {
background-color: rgb(154, 179, 14);
}

table {
table-layout: fixed;
width: 400px;
}

.fake-text-block {
height: 20px;
}
</style>
</head>

<body>
<slot />
</body>

</html>
</container>

<rendering>

<div style="position: absolute; top: 0px; left: 0px; height: 100px; width: 400px;">
<div style="position: absolute; top: 20px; left: 10px; height: 20px; width: 380px;">
<div style="position: absolute; top: 0px; left: 0px; height: 20px; width: 380px;">
<div style="position: absolute; top: 0px; left: 0px; height: 20px; width: 185px;" class="color1">
</div>
<div style="position: absolute; top: 0px; left: 195px; height: 20px; width: 185px;" class="color1">
</div>
</div>
</div>
<div style="position: absolute; top: 60px; left: 10px; height: 20px; width: 380px;">
<div style="position: absolute; top: 0px; left: 0px; height: 20px; width: 380px;">
<div style="position: absolute; top: 0px; left: 0px; height: 20px; width: 185px;" class="color2">
</div>
<div style="position: absolute; top: 0px; left: 195px; height: 20px; width: 185px;" class="color2">
</div>
</div>
</div>
</div>

</rendering>

<rendering>
<table>
<thead class="color1">
<tr>
<th class="fake-text-block" />
<th class="fake-text-block" />
</tr>
</thead>
<tbody>
<tr class="color2">
<td class="fake-text-block" />
<td class="fake-text-block" />
</tr>
</tbody>
</table>
</rendering>

</test>

<test name="table: fixed + border separate + spacing" size="320">
<container>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
Expand Down

0 comments on commit 094bf81

Please sign in to comment.