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

Side by Side Diff: Source/core/rendering/RenderTableSection.cpp

Issue 576823004: Move painting code for tables into *Paint classes. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderTableSection.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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. All r ights reserved. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. All r ights reserved.
8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public 11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either 12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version. 13 * version 2 of the License, or (at your option) any later version.
14 * 14 *
15 * This library is distributed in the hope that it will be useful, 15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details. 18 * Library General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU Library General Public License 20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to 21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA. 23 * Boston, MA 02110-1301, USA.
24 */ 24 */
25 25
26 #include "config.h" 26 #include "config.h"
27 #include "core/rendering/RenderTableSection.h" 27 #include "core/rendering/RenderTableSection.h"
28 28
29 #include "core/paint/TableSectionPainter.h"
29 #include <limits> 30 #include <limits>
30 #include "core/rendering/GraphicsContextAnnotator.h" 31 #include "core/rendering/GraphicsContextAnnotator.h"
31 #include "core/rendering/HitTestResult.h" 32 #include "core/rendering/HitTestResult.h"
32 #include "core/rendering/PaintInfo.h" 33 #include "core/rendering/PaintInfo.h"
33 #include "core/rendering/RenderTableCell.h" 34 #include "core/rendering/RenderTableCell.h"
34 #include "core/rendering/RenderTableCol.h" 35 #include "core/rendering/RenderTableCol.h"
35 #include "core/rendering/RenderTableRow.h" 36 #include "core/rendering/RenderTableRow.h"
36 #include "core/rendering/RenderView.h" 37 #include "core/rendering/RenderView.h"
37 #include "core/rendering/SubtreeLayoutScope.h" 38 #include "core/rendering/SubtreeLayoutScope.h"
38 #include "wtf/HashSet.h" 39 #include "wtf/HashSet.h"
39 40
40 namespace blink { 41 namespace blink {
41 42
42 using namespace HTMLNames; 43 using namespace HTMLNames;
43 44
44 // Those 2 variables are used to balance the memory consumption vs the paint inv alidation time on big tables. 45 // This variable is used to balance the memory consumption vs the paint invalida tion time on big tables.
45 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; 46 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75;
46 static float gMaxAllowedOverflowingCellRatioForFastPaintPath = 0.1f;
47 47
48 static inline void setRowLogicalHeightToRowStyleLogicalHeight(RenderTableSection ::RowStruct& row) 48 static inline void setRowLogicalHeightToRowStyleLogicalHeight(RenderTableSection ::RowStruct& row)
49 { 49 {
50 ASSERT(row.rowRenderer); 50 ASSERT(row.rowRenderer);
51 row.logicalHeight = row.rowRenderer->style()->logicalHeight(); 51 row.logicalHeight = row.rowRenderer->style()->logicalHeight();
52 } 52 }
53 53
54 static inline void updateLogicalHeightForCell(RenderTableSection::RowStruct& row , const RenderTableCell* cell) 54 static inline void updateLogicalHeightForCell(RenderTableSection::RowStruct& row , const RenderTableCell* cell)
55 { 55 {
56 // We ignore height settings on rowspan cells. 56 // We ignore height settings on rowspan cells.
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 // Only cells with content have a baseline 1253 // Only cells with content have a baseline
1254 if (cell && cell->contentLogicalHeight()) 1254 if (cell && cell->contentLogicalHeight())
1255 firstLineBaseline = std::max<int>(firstLineBaseline, cell->logicalTo p() + cell->paddingBefore() + cell->borderBefore() + cell->contentLogicalHeight( )); 1255 firstLineBaseline = std::max<int>(firstLineBaseline, cell->logicalTo p() + cell->paddingBefore() + cell->borderBefore() + cell->contentLogicalHeight( ));
1256 } 1256 }
1257 1257
1258 return firstLineBaseline; 1258 return firstLineBaseline;
1259 } 1259 }
1260 1260
1261 void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOff set) 1261 void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOff set)
1262 { 1262 {
1263 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this); 1263 TableSectionPainter(*this).paint(paintInfo, paintOffset);
1264
1265 ASSERT(!needsLayout());
1266 // avoid crashing on bugs that cause us to paint with dirty layout
1267 if (needsLayout())
1268 return;
1269
1270 unsigned totalRows = m_grid.size();
1271 unsigned totalCols = table()->columns().size();
1272
1273 if (!totalRows || !totalCols)
1274 return;
1275
1276 LayoutPoint adjustedPaintOffset = paintOffset + location();
1277
1278 PaintPhase phase = paintInfo.phase;
1279 bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, ForceCont entsClip);
1280 paintObject(paintInfo, adjustedPaintOffset);
1281 if (pushedClip)
1282 popContentsClip(paintInfo, phase, adjustedPaintOffset);
1283
1284 if ((phase == PaintPhaseOutline || phase == PaintPhaseSelfOutline) && style( )->visibility() == VISIBLE)
1285 paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
1286 }
1287
1288 static inline bool compareCellPositions(RenderTableCell* elem1, RenderTableCell* elem2)
1289 {
1290 return elem1->rowIndex() < elem2->rowIndex();
1291 }
1292
1293 // This comparison is used only when we have overflowing cells as we have an uns orted array to sort. We thus need
1294 // to sort both on rows and columns to properly issue paint invalidations.
1295 static inline bool compareCellPositionsWithOverflowingCells(RenderTableCell* ele m1, RenderTableCell* elem2)
1296 {
1297 if (elem1->rowIndex() != elem2->rowIndex())
1298 return elem1->rowIndex() < elem2->rowIndex();
1299
1300 return elem1->col() < elem2->col();
1301 }
1302
1303 void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1304 {
1305 LayoutPoint cellPoint = flipForWritingModeForChild(cell, paintOffset);
1306 PaintPhase paintPhase = paintInfo.phase;
1307 RenderTableRow* row = toRenderTableRow(cell->parent());
1308
1309 if (paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChild BlockBackground) {
1310 // We need to handle painting a stack of backgrounds. This stack (from bottom to top) consists of
1311 // the column group, column, row group, row, and then the cell.
1312 RenderTableCol* column = table()->colElement(cell->col());
1313 RenderTableCol* columnGroup = column ? column->enclosingColumnGroup() : 0;
1314
1315 // Column groups and columns first.
1316 // FIXME: Columns and column groups do not currently support opacity, an d they are being painted "too late" in
1317 // the stack, since we have already opened a transparency layer (potenti ally) for the table row group.
1318 // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the
1319 // cell.
1320 cell->paintBackgroundsBehindCell(paintInfo, cellPoint, columnGroup);
1321 cell->paintBackgroundsBehindCell(paintInfo, cellPoint, column);
1322
1323 // Paint the row group next.
1324 cell->paintBackgroundsBehindCell(paintInfo, cellPoint, this);
1325
1326 // Paint the row next, but only if it doesn't have a layer. If a row ha s a layer, it will be responsible for
1327 // painting the row background for the cell.
1328 if (!row->hasSelfPaintingLayer())
1329 cell->paintBackgroundsBehindCell(paintInfo, cellPoint, row);
1330 }
1331 if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()))
1332 cell->paint(paintInfo, cellPoint);
1333 } 1264 }
1334 1265
1335 LayoutRect RenderTableSection::logicalRectForWritingModeAndDirection(const Layou tRect& rect) const 1266 LayoutRect RenderTableSection::logicalRectForWritingModeAndDirection(const Layou tRect& rect) const
1336 { 1267 {
1337 LayoutRect tableAlignedRect(rect); 1268 LayoutRect tableAlignedRect(rect);
1338 1269
1339 flipForWritingMode(tableAlignedRect); 1270 flipForWritingMode(tableAlignedRect);
1340 1271
1341 if (!style()->isHorizontalWritingMode()) 1272 if (!style()->isHorizontalWritingMode())
1342 tableAlignedRect = tableAlignedRect.transposedRect(); 1273 tableAlignedRect = tableAlignedRect.transposedRect();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 if (endColumn == columnPos.size()) 1363 if (endColumn == columnPos.size())
1433 endColumn = columnPos.size() - 1; 1364 endColumn = columnPos.size() - 1;
1434 } 1365 }
1435 1366
1436 return CellSpan(startColumn, endColumn); 1367 return CellSpan(startColumn, endColumn);
1437 } 1368 }
1438 1369
1439 1370
1440 void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa intOffset) 1371 void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa intOffset)
1441 { 1372 {
1442 LayoutRect localPaintInvalidationRect = paintInfo.rect; 1373 TableSectionPainter(*this).paintObject(paintInfo, paintOffset);
1443 localPaintInvalidationRect.moveBy(-paintOffset);
1444
1445 LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(localPai ntInvalidationRect);
1446
1447 CellSpan dirtiedRows = this->dirtiedRows(tableAlignedRect);
1448 CellSpan dirtiedColumns = this->dirtiedColumns(tableAlignedRect);
1449
1450 if (dirtiedColumns.start() < dirtiedColumns.end()) {
1451 if (!m_hasMultipleCellLevels && !m_overflowingCells.size()) {
1452 if (paintInfo.phase == PaintPhaseCollapsedTableBorders) {
1453 // Collapsed borders are painted from the bottom right to the to p left so that precedence
1454 // due to cell position is respected.
1455 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r- -) {
1456 unsigned row = r - 1;
1457 for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.s tart(); c--) {
1458 unsigned col = c - 1;
1459 CellStruct& current = cellAt(row, col);
1460 RenderTableCell* cell = current.primaryCell();
1461 if (!cell || (row > dirtiedRows.start() && primaryCellAt (row - 1, col) == cell) || (col > dirtiedColumns.start() && primaryCellAt(row, c ol - 1) == cell))
1462 continue;
1463 LayoutPoint cellPoint = flipForWritingModeForChild(cell, paintOffset);
1464 cell->paintCollapsedBorders(paintInfo, cellPoint);
1465 }
1466 }
1467 } else {
1468 // Draw the dirty cells in the order that they appear.
1469 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r+ +) {
1470 RenderTableRow* row = m_grid[r].rowRenderer;
1471 if (row && !row->hasSelfPaintingLayer())
1472 row->paintOutlineForRowIfNeeded(paintInfo, paintOffset);
1473 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns .end(); c++) {
1474 CellStruct& current = cellAt(r, c);
1475 RenderTableCell* cell = current.primaryCell();
1476 if (!cell || (r > dirtiedRows.start() && primaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && primaryCellAt(r, c - 1) == c ell))
1477 continue;
1478 paintCell(cell, paintInfo, paintOffset);
1479 }
1480 }
1481 }
1482 } else {
1483 // The overflowing cells should be scarce to avoid adding a lot of c ells to the HashSet.
1484 #if ENABLE(ASSERT)
1485 unsigned totalRows = m_grid.size();
1486 unsigned totalCols = table()->columns().size();
1487 ASSERT(m_overflowingCells.size() < totalRows * totalCols * gMaxAllow edOverflowingCellRatioForFastPaintPath);
1488 #endif
1489
1490 // To make sure we properly paint invalidate the section, we paint i nvalidated all the overflowing cells that we collected.
1491 Vector<RenderTableCell*> cells;
1492 copyToVector(m_overflowingCells, cells);
1493
1494 HashSet<RenderTableCell*> spanningCells;
1495
1496 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
1497 RenderTableRow* row = m_grid[r].rowRenderer;
1498 if (row && !row->hasSelfPaintingLayer())
1499 row->paintOutlineForRowIfNeeded(paintInfo, paintOffset);
1500 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end (); c++) {
1501 CellStruct& current = cellAt(r, c);
1502 if (!current.hasCells())
1503 continue;
1504 for (unsigned i = 0; i < current.cells.size(); ++i) {
1505 if (m_overflowingCells.contains(current.cells[i]))
1506 continue;
1507
1508 if (current.cells[i]->rowSpan() > 1 || current.cells[i]- >colSpan() > 1) {
1509 if (!spanningCells.add(current.cells[i]).isNewEntry)
1510 continue;
1511 }
1512
1513 cells.append(current.cells[i]);
1514 }
1515 }
1516 }
1517
1518 // Sort the dirty cells by paint order.
1519 if (!m_overflowingCells.size())
1520 std::stable_sort(cells.begin(), cells.end(), compareCellPosition s);
1521 else
1522 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOv erflowingCells);
1523
1524 if (paintInfo.phase == PaintPhaseCollapsedTableBorders) {
1525 for (unsigned i = cells.size(); i > 0; --i) {
1526 LayoutPoint cellPoint = flipForWritingModeForChild(cells[i - 1], paintOffset);
1527 cells[i - 1]->paintCollapsedBorders(paintInfo, cellPoint);
1528 }
1529 } else {
1530 for (unsigned i = 0; i < cells.size(); ++i)
1531 paintCell(cells[i], paintInfo, paintOffset);
1532 }
1533 }
1534 }
1535 } 1374 }
1536 1375
1537 void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*) 1376 void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*)
1538 { 1377 {
1539 // FIXME: Examine cells and issue paint invalidations of only the rect the i mage paints in. 1378 // FIXME: Examine cells and issue paint invalidations of only the rect the i mage paints in.
1540 setShouldDoFullPaintInvalidation(true); 1379 setShouldDoFullPaintInvalidation(true);
1541 } 1380 }
1542 1381
1543 void RenderTableSection::recalcCells() 1382 void RenderTableSection::recalcCells()
1544 { 1383 {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 // FIXME: The table's direction should determine our row's direction, not th e section's (see bug 96691). 1609 // FIXME: The table's direction should determine our row's direction, not th e section's (see bug 96691).
1771 if (!style()->isLeftToRightDirection()) 1610 if (!style()->isLeftToRightDirection())
1772 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing); 1611 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing);
1773 else 1612 else
1774 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing); 1613 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing);
1775 1614
1776 cell->setLogicalLocation(cellLocation); 1615 cell->setLogicalLocation(cellLocation);
1777 } 1616 }
1778 1617
1779 } // namespace blink 1618 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderTableSection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698