Skip to content

Commit

Permalink
wip, refact and fix
Browse files Browse the repository at this point in the history
  • Loading branch information
pauloamed committed Nov 21, 2024
1 parent b21d7e1 commit fd2a6e7
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 93 deletions.
152 changes: 61 additions & 91 deletions src/vaev-layout/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ void advanceUntil(MutCursor<Box> &cursor, Func<bool(Display)> pred) {
}

struct TableCell {
static TableCell const EMPTY;

Math::Vec2u anchorIdx = {};
MutCursor<Box> box = nullptr;

static TableCell const EMPTY;

bool operator==(TableCell const &c) const {
return box == c.box and anchorIdx == c.anchorIdx;
}
Expand Down 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,31 @@ struct TableFormatingContext {
}

void runTableBox(Tree &tree, Input input, Px &currPositionY) {
auto getBackgroundsForCell = [&](usize i, usize j) {
// FIXME:
// col and row (groups or axis) are not boxes per se, but only cover the background of the cell; this is
// more evident in case of spacing: its not the whole area of the row/col that will have the background
// painted, but only the area of the cells (and the spacing part just takes the background of the
// table layout)
// however we cannot use the same row/col box over and over since each box/frag only has 1 final
// coordinate, what is contradicted if we render the same row box for all its cells eg
// cloning the boxes is not a solution since it would modify the box tree, which should be immutable
// maybe creating anon boxes works, similar to what is done in text maybe?

Vec<BackgroundProps> backgrounds;
if (rowHelper[i].axisIdx)
backgrounds.pushBack(rows[rowHelper[i].axisIdx.unwrap()].el.style->backgrounds);
if (rowHelper[i].groupIdx)
backgrounds.pushBack(rowGroups[rowHelper[i].groupIdx.unwrap()].el.style->backgrounds);
if (colHelper[j].axisIdx)
backgrounds.pushBack(cols[colHelper[j].axisIdx.unwrap()].el.style->backgrounds);
if (colHelper[j].groupIdx)
backgrounds.pushBack(colGroups[colHelper[j].groupIdx.unwrap()].el.style->backgrounds);
return backgrounds;
};

// 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 +899,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 @@ -949,18 +918,19 @@ struct TableFormatingContext {
// increase the height of the cell box.
//
// (See https://www.w3.org/TR/CSS22/tables.html#height-layout)
auto cellOutput = layout(
tree,
*cell.box,
{
.commit = Commit::YES,
.knownSize = {
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},
}
);
Input cellInput{
.commit = Commit::YES,
.knownSize = {
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}
};

auto backgroundsFromTable = getBackgroundsForCell(i, j);
cell.box->style->backgrounds.pushFront(backgroundsFromTable);

layout(tree, *cell.box, cellInput);
};
}
}
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 fd2a6e7

Please sign in to comment.