Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2433473002: Move table row pagination strut insertion to the first layout pass. (Closed)
Patch Set: Rebaseline semi-manually thank you very much. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutTableSection.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index fc9f44e0d97d2a0a8977329d1046105973921c7e..25fb70ab90f774205c1b74dae700f9f6112bb61c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -860,6 +860,9 @@ int LayoutTableSection::calcRowLogicalHeight() {
m_grid[r].baseline = -1;
int baselineDescent = 0;
+ if (state.isPaginated() && m_grid[r].rowLayoutObject)
+ m_rowPos[r] += m_grid[r].rowLayoutObject->paginationStrut().ceil();
+
if (m_grid[r].logicalHeight.isSpecified()) {
// Our base size is the biggest logical height from our cells' styles
// (excluding row spanning cells).
@@ -978,8 +981,7 @@ void LayoutTableSection::layout() {
}
rowLayoutObject->layoutIfNeeded();
if (state.isPaginated()) {
- rowLayoutObject->setLogicalHeight(
- LayoutUnit(logicalHeightForRow(*rowLayoutObject)));
+ adjustRowForPagination(*rowLayoutObject, layouter);
rowLogicalTop = rowLayoutObject->logicalBottom();
rowLogicalTop += LayoutUnit(table()->vBorderSpacing());
}
@@ -1118,57 +1120,29 @@ void LayoutTableSection::layoutRows() {
int vspacing = table()->vBorderSpacing();
unsigned nEffCols = table()->numEffectiveColumns();
- bool isPaginated = view()->layoutState()->isPaginated();
-
- if (isPaginated) {
- LayoutTableSection* header = table()->header();
- // If we're a table header nested inside a table cell then we want to repeat
- // on each page, but below the header we're nested inside. Note we don't try
- // to match the padding on the cell on each repeated header.
- if (header && header == this)
- setOffsetForRepeatingHeader(
- view()->layoutState()->heightOffsetForTableHeaders());
- }
-
LayoutState state(*this, locationOffset());
+ // Set the rows' location and size.
for (unsigned r = 0; r < totalRows; r++) {
- // Set the row's x/y position and width/height.
LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject;
- int paginationStrutOnRow = 0;
if (rowLayoutObject) {
rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r]));
rowLayoutObject->setLogicalWidth(logicalWidth());
- rowLayoutObject->setLogicalHeight(
- LayoutUnit(m_rowPos[r + 1] - m_rowPos[r] - vspacing));
- rowLayoutObject->updateLayerTransformAfterLayout();
- if (isPaginated) {
- paginationStrutOnRow =
- paginationStrutForRow(rowLayoutObject, LayoutUnit(m_rowPos[r]));
- rowLayoutObject->setPaginationStrut(LayoutUnit(paginationStrutOnRow));
- bool rowIsAtTopOfColumn =
- state.heightOffsetForTableHeaders() &&
- pageRemainingLogicalHeightForOffset(LayoutUnit(m_rowPos[r]),
- AssociateWithLatterPage) ==
- pageLogicalHeightForOffset(LayoutUnit(m_rowPos[r]));
- if (paginationStrutOnRow || rowIsAtTopOfColumn) {
- // If there isn't room for at least one content row on a page with a
- // header group, then we won't repeat the header on each page.
- if (!r && table()->header() &&
- table()->sectionAbove(this) == table()->header() &&
- table()->header()->getPaginationBreakability() != AllowAnyBreaks)
- state.setHeightOffsetForTableHeaders(
- state.heightOffsetForTableHeaders() -
- table()->header()->logicalHeight());
- // If we have a header group we will paint it at the top of each page,
- // move the rows down to accomodate it.
- paginationStrutOnRow += state.heightOffsetForTableHeaders().toInt();
- for (unsigned rowIndex = r; rowIndex <= totalRows; rowIndex++)
- m_rowPos[rowIndex] += paginationStrutOnRow;
- }
+ LayoutUnit rowLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
+ if (state.isPaginated() && r + 1 < totalRows) {
+ // If the next row has a pagination strut, we need to subtract it. It
+ // should not be included in this row's height.
+ if (LayoutTableRow* nextRowObject = m_grid[r + 1].rowLayoutObject)
+ rowLogicalHeight -= nextRowObject->paginationStrut();
}
+ rowLayoutObject->setLogicalHeight(rowLogicalHeight);
+ rowLayoutObject->updateLayerTransformAfterLayout();
}
+ }
+ // Vertically align and flex the cells in each row.
+ for (unsigned r = 0; r < totalRows; r++) {
+ LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject;
int rowHeightIncreaseForPagination = INT_MIN;
for (unsigned c = 0; c < nEffCols; c++) {
@@ -1178,14 +1152,25 @@ void LayoutTableSection::layoutRows() {
if (!cell || cs.inColSpan)
continue;
- int rowIndex = cell->rowIndex();
- int rHeight =
- m_rowPos[rowIndex + cell->rowSpan()] - m_rowPos[rowIndex] - vspacing;
+ if (cell->rowIndex() != r)
+ continue; // Rowspanned cells are handled in the first row they occur.
+
+ int rHeight;
+ int rowLogicalTop;
+ unsigned rowSpan = std::max(1U, cell->rowSpan());
+ unsigned endRowIndex = std::min(r + rowSpan, totalRows) - 1;
+ LayoutTableRow* lastRowObject = m_grid[endRowIndex].rowLayoutObject;
+ if (lastRowObject && rowLayoutObject) {
+ rowLogicalTop = rowLayoutObject->logicalTop().toInt();
+ rHeight = lastRowObject->logicalBottom().toInt() - rowLogicalTop;
+ } else {
+ rHeight = m_rowPos[endRowIndex + 1] - m_rowPos[r] - vspacing;
+ rowLogicalTop = m_rowPos[r];
+ }
relayoutCellIfFlexed(*cell, r, rHeight);
SubtreeLayoutScope layouter(*cell);
- LayoutUnit rowLogicalTop(m_rowPos[rowIndex]);
EVerticalAlign cellVerticalAlign;
// If the cell crosses a fragmentainer boundary, just align it at the
// top. That's how it was laid out initially, before we knew the final
@@ -1194,7 +1179,7 @@ void LayoutTableSection::layoutRows() {
// the requested alignment. Give up instead of risking circular
// dependencies and unstable layout.
if (state.isPaginated() &&
- crossesPageBoundary(rowLogicalTop, LayoutUnit(rHeight)))
+ crossesPageBoundary(LayoutUnit(rowLogicalTop), LayoutUnit(rHeight)))
cellVerticalAlign = VerticalAlignTop;
else
cellVerticalAlign = cell->style()->verticalAlign();
@@ -1998,6 +1983,54 @@ int LayoutTableSection::logicalHeightForRow(
return logicalHeight;
}
+void LayoutTableSection::adjustRowForPagination(LayoutTableRow& rowObject,
+ SubtreeLayoutScope& layouter) {
+ LayoutState& state = *view()->layoutState();
+ rowObject.setPaginationStrut(LayoutUnit());
+ rowObject.setLogicalHeight(LayoutUnit(logicalHeightForRow(rowObject)));
+ int paginationStrut =
+ paginationStrutForRow(&rowObject, rowObject.logicalTop());
+ if (!paginationStrut) {
+ bool rowIsAtTopOfColumn =
+ state.heightOffsetForTableHeaders() &&
+ pageLogicalHeightForOffset(rowObject.logicalTop()) ==
+ pageRemainingLogicalHeightForOffset(rowObject.logicalTop(),
+ AssociateWithLatterPage);
+ if (!rowIsAtTopOfColumn)
+ return;
+ }
+ // We need to push this row to the next fragmentainer. If there are repeated
+ // table headers, we need to make room for those at the top of the next
+ // fragmentainer, above this row. Otherwise, this row will just go at the top
+ // of the next fragmentainer.
+
+ // If there isn't room for at least one content row on a page with a
+ // header group, then we won't repeat the header on each page.
+ LayoutTableSection* header = table()->header();
+ if (!rowObject.rowIndex() && header &&
+ table()->sectionAbove(this) == header &&
+ header->getPaginationBreakability() != AllowAnyBreaks) {
+ state.setHeightOffsetForTableHeaders(state.heightOffsetForTableHeaders() -
+ header->logicalHeight());
+ }
+ // If we have a header group we will paint it at the top of each page,
+ // move the rows down to accomodate it.
+ paginationStrut += state.heightOffsetForTableHeaders().toInt();
+ rowObject.setPaginationStrut(LayoutUnit(paginationStrut));
+
+ // We have inserted a pagination strut before the row. Adjust the logical top
+ // and re-lay out. We no longer want to break inside the row, but rather
+ // *before* it. From the previous layout pass, there are most likely
+ // pagination struts inside some cell in this row that we need to get rid of.
+ rowObject.setLogicalTop(rowObject.logicalTop() + paginationStrut);
+ layouter.setChildNeedsLayout(&rowObject);
+ rowObject.layoutIfNeeded();
+
+ // It's very likely that re-laying out (and nuking pagination struts inside
+ // cells) gave us a new height.
+ rowObject.setLogicalHeight(LayoutUnit(logicalHeightForRow(rowObject)));
+}
+
bool LayoutTableSection::isRepeatingHeaderGroup() const {
if (getPaginationBreakability() == LayoutBox::AllowAnyBreaks)
return false;
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutTableSection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698