From fd2a6e74c1607ead271da0996c5cd276974b85a9 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Thu, 21 Nov 2024 10:50:42 +0100 Subject: [PATCH] wip, refact and fix --- src/vaev-layout/table.cpp | 152 ++++++++++++++-------------------- tests/css/display-table.xhtml | 95 ++++++++++++++++++++- 2 files changed, 154 insertions(+), 93 deletions(-) diff --git a/src/vaev-layout/table.cpp b/src/vaev-layout/table.cpp index 63d41df..6c8f68a 100644 --- a/src/vaev-layout/table.cpp +++ b/src/vaev-layout/table.cpp @@ -12,11 +12,11 @@ void advanceUntil(MutCursor &cursor, Func pred) { } struct TableCell { + static TableCell const EMPTY; + Math::Vec2u anchorIdx = {}; MutCursor box = nullptr; - static TableCell const EMPTY; - bool operator==(TableCell const &c) const { return box == c.box and anchorIdx == c.anchorIdx; } @@ -796,12 +796,34 @@ struct TableFormatingContext { } } + struct AxisHelper { + Opt groupIdx = NONE; + Opt axisIdx = NONE; + }; + + Vec buildAxisHelper(Vec const &axes, Vec const &groups, usize len) { + Vec helper{Buf::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 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). @@ -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 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 colWidthPref{colWidth}, rowHeightPref{rowHeight}; Px currPositionX{input.position.x}; @@ -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}; @@ -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); }; } } diff --git a/tests/css/display-table.xhtml b/tests/css/display-table.xhtml index 6cc4e66..7e35573 100644 --- a/tests/css/display-table.xhtml +++ b/tests/css/display-table.xhtml @@ -1059,7 +1059,7 @@ } .yellow { - background-color: rgba(255, 255, 0, 0.37); + background-color: rgba(255, 255, 0, 0.445); } .gray { @@ -1067,7 +1067,7 @@ } .orange { - background-color: rgba(231, 134, 8, 0.603); + background-color: rgba(231, 134, 8, 0.253); } .purple { @@ -1274,6 +1274,97 @@ + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + +
+ +
+ +
+
+ +
+