| OLD | NEW |
| 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 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "core/rendering/RenderTableCol.h" | 34 #include "core/rendering/RenderTableCol.h" |
| 35 #include "core/rendering/RenderTableRow.h" | 35 #include "core/rendering/RenderTableRow.h" |
| 36 #include "core/rendering/RenderView.h" | 36 #include "core/rendering/RenderView.h" |
| 37 #include "core/rendering/SubtreeLayoutScope.h" | 37 #include "core/rendering/SubtreeLayoutScope.h" |
| 38 #include "wtf/HashSet.h" | 38 #include "wtf/HashSet.h" |
| 39 | 39 |
| 40 namespace blink { | 40 namespace blink { |
| 41 | 41 |
| 42 using namespace HTMLNames; | 42 using namespace HTMLNames; |
| 43 | 43 |
| 44 // Those 2 variables are used to balance the memory consumption vs the repaint t
ime on big tables. | 44 // Those 2 variables are used to balance the memory consumption vs the paint inv
alidation time on big tables. |
| 45 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; | 45 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; |
| 46 static float gMaxAllowedOverflowingCellRatioForFastPaintPath = 0.1f; | 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) |
| (...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 // either. It's at least stable though and won't result in an in
finite # of relayouts that may never stabilize. | 1006 // either. It's at least stable though and won't result in an in
finite # of relayouts that may never stabilize. |
| 1007 LayoutUnit oldLogicalHeight = cell->logicalHeight(); | 1007 LayoutUnit oldLogicalHeight = cell->logicalHeight(); |
| 1008 if (oldLogicalHeight > rHeight) | 1008 if (oldLogicalHeight > rHeight) |
| 1009 rowHeightIncreaseForPagination = std::max<int>(rowHeightIncr
easeForPagination, oldLogicalHeight - rHeight); | 1009 rowHeightIncreaseForPagination = std::max<int>(rowHeightIncr
easeForPagination, oldLogicalHeight - rHeight); |
| 1010 cell->setLogicalHeight(rHeight); | 1010 cell->setLogicalHeight(rHeight); |
| 1011 cell->computeOverflow(oldLogicalHeight, false); | 1011 cell->computeOverflow(oldLogicalHeight, false); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 LayoutSize childOffset(cell->location() - oldCellRect.location()); | 1014 LayoutSize childOffset(cell->location() - oldCellRect.location()); |
| 1015 if (childOffset.width() || childOffset.height()) { | 1015 if (childOffset.width() || childOffset.height()) { |
| 1016 // If the child moved, we have to repaint it as well as any floa
ting/positioned | 1016 // If the child moved, we have to issue paint invalidations to i
t as well as any floating/positioned |
| 1017 // descendants. An exception is if we need a layout. In this cas
e, we know we're going to | 1017 // descendants. An exception is if we need a layout. In this cas
e, we know we're going to |
| 1018 // repaint ourselves (and the child) anyway. | 1018 // issue paint invalidations ourselves (and the child) anyway. |
| 1019 if (!table()->selfNeedsLayout() && cell->checkForPaintInvalidati
on()) | 1019 if (!table()->selfNeedsLayout() && cell->checkForPaintInvalidati
on()) |
| 1020 cell->setMayNeedPaintInvalidation(true); | 1020 cell->setMayNeedPaintInvalidation(true); |
| 1021 } | 1021 } |
| 1022 } | 1022 } |
| 1023 if (rowHeightIncreaseForPagination) { | 1023 if (rowHeightIncreaseForPagination) { |
| 1024 for (unsigned rowIndex = r + 1; rowIndex <= totalRows; rowIndex++) | 1024 for (unsigned rowIndex = r + 1; rowIndex <= totalRows; rowIndex++) |
| 1025 m_rowPos[rowIndex] += rowHeightIncreaseForPagination; | 1025 m_rowPos[rowIndex] += rowHeightIncreaseForPagination; |
| 1026 for (unsigned c = 0; c < nEffCols; ++c) { | 1026 for (unsigned c = 0; c < nEffCols; ++c) { |
| 1027 WillBeHeapVector<RawPtrWillBeMember<RenderTableCell>, 1>& cells
= cellAt(r, c).cells; | 1027 WillBeHeapVector<RawPtrWillBeMember<RenderTableCell>, 1>& cells
= cellAt(r, c).cells; |
| 1028 for (size_t i = 0; i < cells.size(); ++i) { | 1028 for (size_t i = 0; i < cells.size(); ++i) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 if ((phase == PaintPhaseOutline || phase == PaintPhaseSelfOutline) && style(
)->visibility() == VISIBLE) | 1243 if ((phase == PaintPhaseOutline || phase == PaintPhaseSelfOutline) && style(
)->visibility() == VISIBLE) |
| 1244 paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size())); | 1244 paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size())); |
| 1245 } | 1245 } |
| 1246 | 1246 |
| 1247 static inline bool compareCellPositions(RenderTableCell* elem1, RenderTableCell*
elem2) | 1247 static inline bool compareCellPositions(RenderTableCell* elem1, RenderTableCell*
elem2) |
| 1248 { | 1248 { |
| 1249 return elem1->rowIndex() < elem2->rowIndex(); | 1249 return elem1->rowIndex() < elem2->rowIndex(); |
| 1250 } | 1250 } |
| 1251 | 1251 |
| 1252 // This comparison is used only when we have overflowing cells as we have an uns
orted array to sort. We thus need | 1252 // This comparison is used only when we have overflowing cells as we have an uns
orted array to sort. We thus need |
| 1253 // to sort both on rows and columns to properly repaint. | 1253 // to sort both on rows and columns to properly issue paint invalidations. |
| 1254 static inline bool compareCellPositionsWithOverflowingCells(RenderTableCell* ele
m1, RenderTableCell* elem2) | 1254 static inline bool compareCellPositionsWithOverflowingCells(RenderTableCell* ele
m1, RenderTableCell* elem2) |
| 1255 { | 1255 { |
| 1256 if (elem1->rowIndex() != elem2->rowIndex()) | 1256 if (elem1->rowIndex() != elem2->rowIndex()) |
| 1257 return elem1->rowIndex() < elem2->rowIndex(); | 1257 return elem1->rowIndex() < elem2->rowIndex(); |
| 1258 | 1258 |
| 1259 return elem1->col() < elem2->col(); | 1259 return elem1->col() < elem2->col(); |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo,
const LayoutPoint& paintOffset) | 1262 void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo,
const LayoutPoint& paintOffset) |
| 1263 { | 1263 { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 return tableAlignedRect; | 1308 return tableAlignedRect; |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 CellSpan RenderTableSection::dirtiedRows(const LayoutRect& damageRect) const | 1311 CellSpan RenderTableSection::dirtiedRows(const LayoutRect& damageRect) const |
| 1312 { | 1312 { |
| 1313 if (m_forceSlowPaintPathWithOverflowingCell) | 1313 if (m_forceSlowPaintPathWithOverflowingCell) |
| 1314 return fullTableRowSpan(); | 1314 return fullTableRowSpan(); |
| 1315 | 1315 |
| 1316 CellSpan coveredRows = spannedRows(damageRect); | 1316 CellSpan coveredRows = spannedRows(damageRect); |
| 1317 | 1317 |
| 1318 // To repaint the border we might need to repaint first or last row even if
they are not spanned themselves. | 1318 // To issue paint invalidations for the border we might need to paint invali
date the first or last row even if they are not spanned themselves. |
| 1319 if (coveredRows.start() >= m_rowPos.size() - 1 && m_rowPos[m_rowPos.size() -
1] + table()->outerBorderAfter() >= damageRect.y()) | 1319 if (coveredRows.start() >= m_rowPos.size() - 1 && m_rowPos[m_rowPos.size() -
1] + table()->outerBorderAfter() >= damageRect.y()) |
| 1320 --coveredRows.start(); | 1320 --coveredRows.start(); |
| 1321 | 1321 |
| 1322 if (!coveredRows.end() && m_rowPos[0] - table()->outerBorderBefore() <= dama
geRect.maxY()) | 1322 if (!coveredRows.end() && m_rowPos[0] - table()->outerBorderBefore() <= dama
geRect.maxY()) |
| 1323 ++coveredRows.end(); | 1323 ++coveredRows.end(); |
| 1324 | 1324 |
| 1325 return coveredRows; | 1325 return coveredRows; |
| 1326 } | 1326 } |
| 1327 | 1327 |
| 1328 CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const | 1328 CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const |
| 1329 { | 1329 { |
| 1330 if (m_forceSlowPaintPathWithOverflowingCell) | 1330 if (m_forceSlowPaintPathWithOverflowingCell) |
| 1331 return fullTableColumnSpan(); | 1331 return fullTableColumnSpan(); |
| 1332 | 1332 |
| 1333 CellSpan coveredColumns = spannedColumns(damageRect); | 1333 CellSpan coveredColumns = spannedColumns(damageRect); |
| 1334 | 1334 |
| 1335 const Vector<int>& columnPos = table()->columnPositions(); | 1335 const Vector<int>& columnPos = table()->columnPositions(); |
| 1336 // To repaint the border we might need to repaint first or last column even
if they are not spanned themselves. | 1336 // To issue paint invalidations for the border we might need to paint invali
date the first or last column even if they are not spanned themselves. |
| 1337 if (coveredColumns.start() >= columnPos.size() - 1 && columnPos[columnPos.si
ze() - 1] + table()->outerBorderEnd() >= damageRect.x()) | 1337 if (coveredColumns.start() >= columnPos.size() - 1 && columnPos[columnPos.si
ze() - 1] + table()->outerBorderEnd() >= damageRect.x()) |
| 1338 --coveredColumns.start(); | 1338 --coveredColumns.start(); |
| 1339 | 1339 |
| 1340 if (!coveredColumns.end() && columnPos[0] - table()->outerBorderStart() <= d
amageRect.maxX()) | 1340 if (!coveredColumns.end() && columnPos[0] - table()->outerBorderStart() <= d
amageRect.maxX()) |
| 1341 ++coveredColumns.end(); | 1341 ++coveredColumns.end(); |
| 1342 | 1342 |
| 1343 return coveredColumns; | 1343 return coveredColumns; |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const | 1346 CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 if (endColumn == columnPos.size()) | 1391 if (endColumn == columnPos.size()) |
| 1392 endColumn = columnPos.size() - 1; | 1392 endColumn = columnPos.size() - 1; |
| 1393 } | 1393 } |
| 1394 | 1394 |
| 1395 return CellSpan(startColumn, endColumn); | 1395 return CellSpan(startColumn, endColumn); |
| 1396 } | 1396 } |
| 1397 | 1397 |
| 1398 | 1398 |
| 1399 void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) | 1399 void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) |
| 1400 { | 1400 { |
| 1401 LayoutRect localRepaintRect = paintInfo.rect; | 1401 LayoutRect localPaintInvalidationRect = paintInfo.rect; |
| 1402 localRepaintRect.moveBy(-paintOffset); | 1402 localPaintInvalidationRect.moveBy(-paintOffset); |
| 1403 | 1403 |
| 1404 LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(localRep
aintRect); | 1404 LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(localPai
ntInvalidationRect); |
| 1405 | 1405 |
| 1406 CellSpan dirtiedRows = this->dirtiedRows(tableAlignedRect); | 1406 CellSpan dirtiedRows = this->dirtiedRows(tableAlignedRect); |
| 1407 CellSpan dirtiedColumns = this->dirtiedColumns(tableAlignedRect); | 1407 CellSpan dirtiedColumns = this->dirtiedColumns(tableAlignedRect); |
| 1408 | 1408 |
| 1409 if (dirtiedColumns.start() < dirtiedColumns.end()) { | 1409 if (dirtiedColumns.start() < dirtiedColumns.end()) { |
| 1410 if (!m_hasMultipleCellLevels && !m_overflowingCells.size()) { | 1410 if (!m_hasMultipleCellLevels && !m_overflowingCells.size()) { |
| 1411 if (paintInfo.phase == PaintPhaseCollapsedTableBorders) { | 1411 if (paintInfo.phase == PaintPhaseCollapsedTableBorders) { |
| 1412 // Collapsed borders are painted from the bottom right to the to
p left so that precedence | 1412 // Collapsed borders are painted from the bottom right to the to
p left so that precedence |
| 1413 // due to cell position is respected. | 1413 // due to cell position is respected. |
| 1414 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r-
-) { | 1414 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r-
-) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1439 } | 1439 } |
| 1440 } | 1440 } |
| 1441 } else { | 1441 } else { |
| 1442 // The overflowing cells should be scarce to avoid adding a lot of c
ells to the HashSet. | 1442 // The overflowing cells should be scarce to avoid adding a lot of c
ells to the HashSet. |
| 1443 #if ENABLE(ASSERT) | 1443 #if ENABLE(ASSERT) |
| 1444 unsigned totalRows = m_grid.size(); | 1444 unsigned totalRows = m_grid.size(); |
| 1445 unsigned totalCols = table()->columns().size(); | 1445 unsigned totalCols = table()->columns().size(); |
| 1446 ASSERT(m_overflowingCells.size() < totalRows * totalCols * gMaxAllow
edOverflowingCellRatioForFastPaintPath); | 1446 ASSERT(m_overflowingCells.size() < totalRows * totalCols * gMaxAllow
edOverflowingCellRatioForFastPaintPath); |
| 1447 #endif | 1447 #endif |
| 1448 | 1448 |
| 1449 // To make sure we properly repaint the section, we repaint all the
overflowing cells that we collected. | 1449 // To make sure we properly paint invalidate the section, we paint i
nvalidated all the overflowing cells that we collected. |
| 1450 Vector<RenderTableCell*> cells; | 1450 Vector<RenderTableCell*> cells; |
| 1451 copyToVector(m_overflowingCells, cells); | 1451 copyToVector(m_overflowingCells, cells); |
| 1452 | 1452 |
| 1453 HashSet<RenderTableCell*> spanningCells; | 1453 HashSet<RenderTableCell*> spanningCells; |
| 1454 | 1454 |
| 1455 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 1455 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 1456 RenderTableRow* row = m_grid[r].rowRenderer; | 1456 RenderTableRow* row = m_grid[r].rowRenderer; |
| 1457 if (row && !row->hasSelfPaintingLayer()) | 1457 if (row && !row->hasSelfPaintingLayer()) |
| 1458 row->paintOutlineForRowIfNeeded(paintInfo, paintOffset); | 1458 row->paintOutlineForRowIfNeeded(paintInfo, paintOffset); |
| 1459 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end
(); c++) { | 1459 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end
(); c++) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1488 } else { | 1488 } else { |
| 1489 for (unsigned i = 0; i < cells.size(); ++i) | 1489 for (unsigned i = 0; i < cells.size(); ++i) |
| 1490 paintCell(cells[i], paintInfo, paintOffset); | 1490 paintCell(cells[i], paintInfo, paintOffset); |
| 1491 } | 1491 } |
| 1492 } | 1492 } |
| 1493 } | 1493 } |
| 1494 } | 1494 } |
| 1495 | 1495 |
| 1496 void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*) | 1496 void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*) |
| 1497 { | 1497 { |
| 1498 // FIXME: Examine cells and repaint only the rect the image paints in. | 1498 // FIXME: Examine cells and issue paint invalidations of only the rect the i
mage paints in. |
| 1499 paintInvalidationForWholeRenderer(); | 1499 paintInvalidationForWholeRenderer(); |
| 1500 } | 1500 } |
| 1501 | 1501 |
| 1502 void RenderTableSection::recalcCells() | 1502 void RenderTableSection::recalcCells() |
| 1503 { | 1503 { |
| 1504 ASSERT(m_needsCellRecalc); | 1504 ASSERT(m_needsCellRecalc); |
| 1505 // We reset the flag here to ensure that |addCell| works. This is safe to do
as | 1505 // We reset the flag here to ensure that |addCell| works. This is safe to do
as |
| 1506 // fillRowsWithDefaultStartingAtPosition makes sure we match the table's col
umns | 1506 // fillRowsWithDefaultStartingAtPosition makes sure we match the table's col
umns |
| 1507 // representation. | 1507 // representation. |
| 1508 m_needsCellRecalc = false; | 1508 m_needsCellRecalc = false; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 // FIXME: The table's direction should determine our row's direction, not th
e section's (see bug 96691). | 1728 // FIXME: The table's direction should determine our row's direction, not th
e section's (see bug 96691). |
| 1729 if (!style()->isLeftToRightDirection()) | 1729 if (!style()->isLeftToRightDirection()) |
| 1730 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta
ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] +
horizontalBorderSpacing); | 1730 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta
ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] +
horizontalBorderSpacing); |
| 1731 else | 1731 else |
| 1732 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont
alBorderSpacing); | 1732 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont
alBorderSpacing); |
| 1733 | 1733 |
| 1734 cell->setLogicalLocation(cellLocation); | 1734 cell->setLogicalLocation(cellLocation); |
| 1735 } | 1735 } |
| 1736 | 1736 |
| 1737 } // namespace blink | 1737 } // namespace blink |
| OLD | NEW |