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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2630723002: Fix blink_perf.paint regression about tables (Closed)
Patch Set: Issues fixed in patch set 4 Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 table()->effectiveColumns(); 251 table()->effectiveColumns();
252 unsigned insertionRow = row->rowIndex(); 252 unsigned insertionRow = row->rowIndex();
253 253
254 // ### mozilla still seems to do the old HTML way, even for strict DTD 254 // ### mozilla still seems to do the old HTML way, even for strict DTD
255 // (see the annotation on table cell layouting in the CSS specs and the 255 // (see the annotation on table cell layouting in the CSS specs and the
256 // testcase below: 256 // testcase below:
257 // <TABLE border> 257 // <TABLE border>
258 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 258 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
259 // <TR><TD colspan="2">5 259 // <TR><TD colspan="2">5
260 // </TABLE> 260 // </TABLE>
261 while (m_cCol < numCols(insertionRow) && 261 unsigned nCols = numCols(insertionRow);
262 (cellAt(insertionRow, m_cCol).hasCells() || 262 while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() ||
263 cellAt(insertionRow, m_cCol).inColSpan)) 263 cellAt(insertionRow, m_cCol).inColSpan))
264 m_cCol++; 264 m_cCol++;
265 265
266 updateLogicalHeightForCell(m_grid[insertionRow], cell); 266 updateLogicalHeightForCell(m_grid[insertionRow], cell);
267 267
268 ensureRows(insertionRow + rSpan); 268 ensureRows(insertionRow + rSpan);
269 269
270 m_grid[insertionRow].rowLayoutObject = row; 270 m_grid[insertionRow].rowLayoutObject = row;
271 271
272 unsigned col = m_cCol; 272 unsigned col = m_cCol;
273 // tell the cell where it is 273 // tell the cell where it is
274 bool inColSpan = false; 274 bool inColSpan = false;
275 unsigned colSize = columns.size();
275 while (cSpan) { 276 while (cSpan) {
276 unsigned currentSpan; 277 unsigned currentSpan;
277 if (m_cCol >= columns.size()) { 278 if (m_cCol >= colSize) {
278 table()->appendEffectiveColumn(cSpan); 279 table()->appendEffectiveColumn(cSpan);
279 currentSpan = cSpan; 280 currentSpan = cSpan;
280 } else { 281 } else {
281 if (cSpan < columns[m_cCol].span) 282 if (cSpan < columns[m_cCol].span)
282 table()->splitEffectiveColumn(m_cCol, cSpan); 283 table()->splitEffectiveColumn(m_cCol, cSpan);
283 currentSpan = columns[m_cCol].span; 284 currentSpan = columns[m_cCol].span;
284 } 285 }
285 for (unsigned r = 0; r < rSpan; r++) { 286 for (unsigned r = 0; r < rSpan; r++) {
286 ensureCols(insertionRow + r, m_cCol + 1); 287 ensureCols(insertionRow + r, m_cCol + 1);
287 CellStruct& c = cellAt(insertionRow + r, m_cCol); 288 CellStruct& c = cellAt(insertionRow + r, m_cCol);
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 } 1146 }
1146 rowLayoutObject->setLogicalHeight(rowLogicalHeight); 1147 rowLayoutObject->setLogicalHeight(rowLogicalHeight);
1147 rowLayoutObject->updateLayerTransformAfterLayout(); 1148 rowLayoutObject->updateLayerTransformAfterLayout();
1148 } 1149 }
1149 } 1150 }
1150 1151
1151 // Vertically align and flex the cells in each row. 1152 // Vertically align and flex the cells in each row.
1152 for (unsigned r = 0; r < totalRows; r++) { 1153 for (unsigned r = 0; r < totalRows; r++) {
1153 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; 1154 LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject;
1154 1155
1155 for (unsigned c = 0; c < numCols(r); c++) { 1156 unsigned nCols = numCols(r);
mstensho (USE GERRIT) 2017/01/20 10:02:04 These are good. I was meaning to point it out in t
1157 for (unsigned c = 0; c < nCols; c++) {
1156 CellStruct& cs = cellAt(r, c); 1158 CellStruct& cs = cellAt(r, c);
1157 LayoutTableCell* cell = cs.primaryCell(); 1159 LayoutTableCell* cell = cs.primaryCell();
1158 1160
1159 if (!cell || cs.inColSpan) 1161 if (!cell || cs.inColSpan)
1160 continue; 1162 continue;
1161 1163
1162 if (cell->rowIndex() != r) 1164 if (cell->rowIndex() != r)
1163 continue; // Rowspanned cells are handled in the first row they occur. 1165 continue; // Rowspanned cells are handled in the first row they occur.
1164 1166
1165 int rHeight; 1167 int rHeight;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount; 1267 : gMaxAllowedOverflowingCellRatioForFastPaintPath * totalCellsCount;
1266 1268
1267 m_overflow.reset(); 1269 m_overflow.reset();
1268 m_overflowingCells.clear(); 1270 m_overflowingCells.clear();
1269 m_forceSlowPaintPathWithOverflowingCell = false; 1271 m_forceSlowPaintPathWithOverflowingCell = false;
1270 #if ENABLE(ASSERT) 1272 #if ENABLE(ASSERT)
1271 bool hasOverflowingCell = false; 1273 bool hasOverflowingCell = false;
1272 #endif 1274 #endif
1273 // Now that our height has been determined, add in overflow from cells. 1275 // Now that our height has been determined, add in overflow from cells.
1274 for (unsigned r = 0; r < totalRows; r++) { 1276 for (unsigned r = 0; r < totalRows; r++) {
1275 for (unsigned c = 0; c < numCols(r); c++) { 1277 unsigned nCols = numCols(r);
1278 unsigned nextRowCells = r < totalRows - 1 ? numCols(r + 1) : 0;
1279 for (unsigned c = 0; c < nCols; c++) {
1276 CellStruct& cs = cellAt(r, c); 1280 CellStruct& cs = cellAt(r, c);
1277 LayoutTableCell* cell = cs.primaryCell(); 1281 LayoutTableCell* cell = cs.primaryCell();
1278 if (!cell || cs.inColSpan) 1282 if (!cell || cs.inColSpan)
1279 continue; 1283 continue;
1280 if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) 1284 if (r < totalRows - 1 && c < nextRowCells &&
1285 cell == primaryCellAt(r + 1, c))
1281 continue; 1286 continue;
1282 addOverflowFromChild(cell); 1287 addOverflowFromChild(cell);
1283 #if ENABLE(ASSERT) 1288 #if ENABLE(ASSERT)
1284 hasOverflowingCell |= cell->hasVisualOverflow(); 1289 hasOverflowingCell |= cell->hasVisualOverflow();
1285 #endif 1290 #endif
1286 if (cell->hasVisualOverflow() && 1291 if (cell->hasVisualOverflow() &&
1287 !m_forceSlowPaintPathWithOverflowingCell) { 1292 !m_forceSlowPaintPathWithOverflowingCell) {
1288 m_overflowingCells.add(cell); 1293 m_overflowingCells.add(cell);
1289 if (m_overflowingCells.size() > maxAllowedOverflowingCellsCount) { 1294 if (m_overflowingCells.size() > maxAllowedOverflowingCellsCount) {
1290 // We need to set m_forcesSlowPaintPath only if there is a least one 1295 // We need to set m_forcesSlowPaintPath only if there is a least one
(...skipping 15 matching lines...) Expand all
1306 clearChildNeedsOverflowRecalcAfterStyleChange(); 1311 clearChildNeedsOverflowRecalcAfterStyleChange();
1307 unsigned totalRows = m_grid.size(); 1312 unsigned totalRows = m_grid.size();
1308 bool childrenOverflowChanged = false; 1313 bool childrenOverflowChanged = false;
1309 for (unsigned r = 0; r < totalRows; r++) { 1314 for (unsigned r = 0; r < totalRows; r++) {
1310 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); 1315 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r);
1311 if (!rowLayouter || 1316 if (!rowLayouter ||
1312 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) 1317 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange())
1313 continue; 1318 continue;
1314 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); 1319 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange();
1315 bool rowChildrenOverflowChanged = false; 1320 bool rowChildrenOverflowChanged = false;
1316 for (unsigned c = 0; c < numCols(r); c++) { 1321 unsigned nCols = numCols(r);
1322 for (unsigned c = 0; c < nCols; c++) {
1317 CellStruct& cs = cellAt(r, c); 1323 CellStruct& cs = cellAt(r, c);
1318 LayoutTableCell* cell = cs.primaryCell(); 1324 LayoutTableCell* cell = cs.primaryCell();
1319 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange()) 1325 if (!cell || cs.inColSpan || !cell->needsOverflowRecalcAfterStyleChange())
1320 continue; 1326 continue;
1321 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange(); 1327 rowChildrenOverflowChanged |= cell->recalcOverflowAfterStyleChange();
1322 } 1328 }
1323 if (rowChildrenOverflowChanged) 1329 if (rowChildrenOverflowChanged)
1324 rowLayouter->computeOverflow(); 1330 rowLayouter->computeOverflow();
1325 childrenOverflowChanged |= rowChildrenOverflowChanged; 1331 childrenOverflowChanged |= rowChildrenOverflowChanged;
1326 } 1332 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 const BorderValue& rb = side == BorderBefore 1365 const BorderValue& rb = side == BorderBefore
1360 ? firstRow()->style()->borderBefore() 1366 ? firstRow()->style()->borderBefore()
1361 : lastRow()->style()->borderAfter(); 1367 : lastRow()->style()->borderAfter();
1362 if (rb.style() == BorderStyleHidden) 1368 if (rb.style() == BorderStyleHidden)
1363 return -1; 1369 return -1;
1364 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) 1370 if (rb.style() > BorderStyleHidden && rb.width() > borderWidth)
1365 borderWidth = rb.width(); 1371 borderWidth = rb.width();
1366 1372
1367 bool allHidden = true; 1373 bool allHidden = true;
1368 unsigned r = side == BorderBefore ? 0 : m_grid.size() - 1; 1374 unsigned r = side == BorderBefore ? 0 : m_grid.size() - 1;
1369 for (unsigned c = 0; c < numCols(r); c++) { 1375 unsigned nCols = numCols(r);
1376 for (unsigned c = 0; c < nCols; c++) {
1370 const CellStruct& current = cellAt(r, c); 1377 const CellStruct& current = cellAt(r, c);
1371 if (current.inColSpan || !current.hasCells()) 1378 if (current.inColSpan || !current.hasCells())
1372 continue; 1379 continue;
1373 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); 1380 const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef();
1374 // FIXME: Make this work with perpendicular and flipped cells. 1381 // FIXME: Make this work with perpendicular and flipped cells.
1375 const BorderValue& cb = side == BorderBefore 1382 const BorderValue& cb = side == BorderBefore
1376 ? primaryCellStyle.borderBefore() 1383 ? primaryCellStyle.borderBefore()
1377 : primaryCellStyle.borderAfter(); 1384 : primaryCellStyle.borderAfter();
1378 // FIXME: Don't repeat for the same col group 1385 // FIXME: Don't repeat for the same col group
1379 LayoutTableCol* col = 1386 LayoutTableCol* col =
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 void LayoutTableSection::setNeedsCellRecalc() { 1687 void LayoutTableSection::setNeedsCellRecalc() {
1681 m_needsCellRecalc = true; 1688 m_needsCellRecalc = true;
1682 if (LayoutTable* t = table()) 1689 if (LayoutTable* t = table())
1683 t->setNeedsSectionRecalc(); 1690 t->setNeedsSectionRecalc();
1684 } 1691 }
1685 1692
1686 unsigned LayoutTableSection::numEffectiveColumns() const { 1693 unsigned LayoutTableSection::numEffectiveColumns() const {
1687 unsigned result = 0; 1694 unsigned result = 0;
1688 1695
1689 for (unsigned r = 0; r < m_grid.size(); ++r) { 1696 for (unsigned r = 0; r < m_grid.size(); ++r) {
1690 for (unsigned c = result; c < numCols(r); ++c) { 1697 unsigned nCols = numCols(r);
1698 for (unsigned c = result; c < nCols; ++c) {
1691 const CellStruct& cell = cellAt(r, c); 1699 const CellStruct& cell = cellAt(r, c);
1692 if (cell.hasCells() || cell.inColSpan) 1700 if (cell.hasCells() || cell.inColSpan)
1693 result = c; 1701 result = c;
1694 } 1702 }
1695 } 1703 }
1696 1704
1697 return result + 1; 1705 return result + 1;
1698 } 1706 }
1699 1707
1700 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( 1708 const BorderValue& LayoutTableSection::borderAdjoiningStartCell(
1701 const LayoutTableCell* cell) const { 1709 const LayoutTableCell* cell) const {
1702 ASSERT(cell->isFirstOrLastCellInRow()); 1710 ASSERT(cell->isFirstOrLastCellInRow());
1703 return hasSameDirectionAs(cell) ? style()->borderStart() 1711 return hasSameDirectionAs(cell) ? style()->borderStart()
1704 : style()->borderEnd(); 1712 : style()->borderEnd();
1705 } 1713 }
1706 1714
1707 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( 1715 const BorderValue& LayoutTableSection::borderAdjoiningEndCell(
1708 const LayoutTableCell* cell) const { 1716 const LayoutTableCell* cell) const {
1709 ASSERT(cell->isFirstOrLastCellInRow()); 1717 ASSERT(cell->isFirstOrLastCellInRow());
1710 return hasSameDirectionAs(cell) ? style()->borderEnd() 1718 return hasSameDirectionAs(cell) ? style()->borderEnd()
1711 : style()->borderStart(); 1719 : style()->borderStart();
1712 } 1720 }
1713 1721
1714 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() 1722 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart()
1715 const { 1723 const {
1716 unsigned adjoiningStartCellColumnIndex = 1724 unsigned adjoiningStartCellColumnIndex =
1717 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); 1725 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex();
1718 return primaryCellAt(0, adjoiningStartCellColumnIndex); 1726 return adjoiningStartCellColumnIndex < numCols(0)
1727 ? primaryCellAt(0, adjoiningStartCellColumnIndex)
1728 : nullptr;
1719 } 1729 }
1720 1730
1721 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() 1731 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd()
1722 const { 1732 const {
1723 unsigned adjoiningEndCellColumnIndex = 1733 unsigned adjoiningEndCellColumnIndex =
1724 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; 1734 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0;
1725 return primaryCellAt(0, adjoiningEndCellColumnIndex); 1735 return adjoiningEndCellColumnIndex < numCols(0)
1736 ? primaryCellAt(0, adjoiningEndCellColumnIndex)
1737 : nullptr;
1726 } 1738 }
1727 1739
1728 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { 1740 void LayoutTableSection::appendEffectiveColumn(unsigned pos) {
1729 ASSERT(!m_needsCellRecalc); 1741 ASSERT(!m_needsCellRecalc);
1730 1742
1731 for (unsigned row = 0; row < m_grid.size(); ++row) 1743 for (unsigned row = 0; row < m_grid.size(); ++row)
1732 m_grid[row].row.resize(pos + 1); 1744 m_grid[row].row.resize(pos + 1);
1733 } 1745 }
1734 1746
1735 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { 1747 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1798 LayoutRect hitTestRect = LayoutRect(locationInContainer.boundingBox()); 1810 LayoutRect hitTestRect = LayoutRect(locationInContainer.boundingBox());
1799 hitTestRect.moveBy(-adjustedLocation); 1811 hitTestRect.moveBy(-adjustedLocation);
1800 1812
1801 LayoutRect tableAlignedRect = 1813 LayoutRect tableAlignedRect =
1802 logicalRectForWritingModeAndDirection(hitTestRect); 1814 logicalRectForWritingModeAndDirection(hitTestRect);
1803 CellSpan rowSpan = spannedRows(tableAlignedRect); 1815 CellSpan rowSpan = spannedRows(tableAlignedRect);
1804 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect); 1816 CellSpan columnSpan = spannedEffectiveColumns(tableAlignedRect);
1805 1817
1806 // Now iterate over the spanned rows and columns. 1818 // Now iterate over the spanned rows and columns.
1807 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) { 1819 for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) {
1808 for (unsigned hitColumn = columnSpan.start(); hitColumn < columnSpan.end(); 1820 unsigned nCols = numCols(hitRow);
1809 ++hitColumn) { 1821 for (unsigned hitColumn = columnSpan.start();
1810 if (hitColumn >= numCols(hitRow)) 1822 hitColumn < nCols && hitColumn < columnSpan.end(); ++hitColumn) {
1811 break;
1812
1813 CellStruct& current = cellAt(hitRow, hitColumn); 1823 CellStruct& current = cellAt(hitRow, hitColumn);
1814 1824
1815 // If the cell is empty, there's nothing to do 1825 // If the cell is empty, there's nothing to do
1816 if (!current.hasCells()) 1826 if (!current.hasCells())
1817 continue; 1827 continue;
1818 1828
1819 for (unsigned i = current.cells.size(); i;) { 1829 for (unsigned i = current.cells.size(); i;) {
1820 --i; 1830 --i;
1821 LayoutTableCell* cell = current.cells[i]; 1831 LayoutTableCell* cell = current.cells[i];
1822 LayoutPoint cellPoint = 1832 LayoutPoint cellPoint =
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 // the header in all columns. 2081 // the header in all columns.
2072 // Note that this is in flow thread coordinates, not visual coordinates. The 2082 // Note that this is in flow thread coordinates, not visual coordinates. The
2073 // enclosing LayoutFlowThread will convert to visual coordinates. 2083 // enclosing LayoutFlowThread will convert to visual coordinates.
2074 if (table()->header() == this && isRepeatingHeaderGroup()) 2084 if (table()->header() == this && isRepeatingHeaderGroup())
2075 rect.setHeight(table()->logicalHeight()); 2085 rect.setHeight(table()->logicalHeight());
2076 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, 2086 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect,
2077 flags); 2087 flags);
2078 } 2088 }
2079 2089
2080 } // namespace blink 2090 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698