Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| index bafa7fcfb72de98f97d236a876d42537794452c9..3148d684e32f3adb2ac2be9c047c2ee11130f930 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| @@ -110,21 +110,23 @@ bool LayoutTableCol::canHaveChildren() const |
| LayoutRect LayoutTableCol::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const |
| { |
| - // For now, just paint invalidate the whole table. |
| - // FIXME: Find a better way to do this, e.g., need to paint invalidate all the cells that we |
| - // might have propagated a background color or borders into. |
| - // FIXME: check for paintInvalidationContainer each time here? |
| - |
| - LayoutTable* parentTable = table(); |
| - if (!parentTable) |
| - return LayoutRect(); |
| - return parentTable->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer, paintInvalidationState); |
| + LayoutRect r = positionByCellSpan(); |
| + mapToVisibleRectInAncestorSpace(paintInvalidationContainer, r, paintInvalidationState); |
| + return r; |
| } |
| void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) |
| { |
| // FIXME: Issue paint invalidation of only the rect the image paints in. |
| - setShouldDoFullPaintInvalidation(); |
| + // INVALIDATE ALL THE CHILDREN |
| + |
| + // This does not work, background does not paint |
| + // table()->setShouldDoFullPaintInvalidation(PaintInvalidationFull); |
| + // This ends up with nothing being painted at all |
| + // setShouldDoFullPaintInvalidation(); |
|
Xianzhu
2016/02/23 22:58:27
Why doesn't the logic in LayoutTable::invalidatePa
atotic1
2016/03/15 16:50:47
We do not call invalidatePaintOfSubtreesIfNeeded f
|
| + Vector<LayoutTableCell*> cells = getColumnCells(); |
| + for (auto c = cells.begin(); c != cells.end(); c++) |
| + (*c)->setShouldDoFullPaintInvalidation(); |
| } |
| void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() |
| @@ -154,6 +156,29 @@ LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const |
| return parentColumnGroup; |
| } |
| +LayoutTableCol * LayoutTableCol::lastColumnInGroup() const |
| +{ |
| + ASSERT(this->isTableColumnGroup()); |
| + |
| + LayoutTableCol * endCol = 0; |
| + LayoutTableCol * currentCol = this->nextColumn(); |
| + // if column has children, traverse the children to find last |
| + if (this->firstChild()) { |
| + while (currentCol && currentCol->enclosingColumnGroup() == this) { |
| + endCol = currentCol; |
| + currentCol = currentCol->nextColumn(); |
| + } |
| + } else { // otherwise, if we have span, use that to find next child |
| + auto span = this->span(); |
| + endCol = currentCol; |
| + while (--span > 0 && currentCol) { |
| + currentCol = currentCol->nextColumn(); |
| + endCol = currentCol; |
| + } |
| + } |
| + return endCol; |
| +} |
| + |
| LayoutTableCol* LayoutTableCol::nextColumn() const |
| { |
| // If |this| is a column-group, the next column is the colgroup's first child column. |
| @@ -164,8 +189,10 @@ LayoutTableCol* LayoutTableCol::nextColumn() const |
| LayoutObject* next = nextSibling(); |
| // Failing that, the child is the last column in a column-group, so the next column is the next column/column-group after its column-group. |
| - if (!next && parent()->isLayoutTableCol()) |
| - next = parent()->nextSibling(); |
| + |
| + auto p = parent(); |
| + if (!next && p && p->isLayoutTableCol()) |
|
Xianzhu
2016/02/23 22:58:27
Can parent() be null?
atotic1
2016/03/15 16:50:47
Yes, seen it live when restoring from history.
|
| + next = p->nextSibling(); |
| for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } |
| @@ -194,4 +221,99 @@ const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel |
| return style()->borderEnd(); |
| } |
| +// computes col/colgroup position that only spans cells |
| +LayoutRect LayoutTableCol::positionByCellSpan() const |
| +{ |
| + |
| + LayoutTable * myTable = table(); |
| + LayoutRect position; |
| + |
| + if (!myTable) |
| + return position; |
| + |
| + LayoutTableSection* topSection = myTable->topNonEmptySection(); |
| + LayoutTableSection* bottomSection = myTable->bottomNonEmptySection(); |
| + if (!topSection || !bottomSection) |
| + return position; |
| + |
| + unsigned startColumnIndex; |
| + unsigned endColumnIndex; |
| + |
| + if (isTableColumnGroup()) { |
| + // colgroup position |
| + LayoutTableCol * startColumn = nextColumn(); |
| + LayoutTableCol * endColumn = lastColumnInGroup(); |
| + |
| + if (startColumn && endColumn) { |
| + startColumnIndex = myTable->colElementToCol(startColumn); |
| + endColumnIndex = myTable->colElementToCol(endColumn); |
| + } else { |
| + return position; |
| + } |
| + } else { |
| + // col position |
| + startColumnIndex = myTable->colElementToCol(this); |
| + endColumnIndex = std::min(startColumnIndex + span() - 1, bottomSection->numColumns() - 1); |
| + } |
| + |
| + position = topSection->positionOfIdealCell(0, startColumnIndex); |
| + position.moveBy(topSection->location()); |
| + LayoutRect bottomPosition = bottomSection->positionOfIdealCell(bottomSection->numRows() - 1, endColumnIndex); |
| + bottomPosition.moveBy(bottomSection->location()); |
| + position.unite(bottomPosition); |
| + return position; |
| +} |
| + |
| +// returns indexes to all columns that span this column |
| +Vector<unsigned> LayoutTableCol::getColumnIndexes() const |
| +{ |
| + LayoutTable * myTable = table(); |
| + Vector<unsigned> indexes; |
| + if (isTableColumn()) { |
| + unsigned idx = myTable->colElementToCol(this); |
| + auto span = this->span(); |
| + while (span--) |
| + indexes.append(idx++); |
| + } else { |
| + // isTableColumnGroup |
| + LayoutTableCol* currentCol = nullptr; |
| + auto lastCol = lastColumnInGroup(); |
| + do { |
| + currentCol = currentCol ? currentCol->nextColumn() : nextColumn(); |
| + if (currentCol) { |
| + auto colIndexes = currentCol->getColumnIndexes(); |
| + for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) |
| + indexes.append(*c); |
| + } |
| + } while (currentCol && currentCol != lastCol); |
| + } |
| + return indexes; |
| +} |
| + |
| +// returns all cells inside a column |
| +Vector<LayoutTableCell*> LayoutTableCol::getColumnCells() const |
| +{ |
| + // enumerate all the columns we need |
| + LayoutTable * myTable = table(); |
| + Vector<LayoutTableCell*> cells; |
| + |
| + if (!myTable) // can't do this before table is laid out |
| + return cells; |
| + |
| + auto colIndexes = getColumnIndexes(); |
| + auto section = myTable->topSection(); |
| + // Get all cells from all columns |
| + while (section) { |
| + for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) { |
| + for (unsigned r = 0; r < section->numRows(); r++) { |
| + LayoutTableCell * cell = section->primaryCellAt(r, *c); |
| + if (cell && cell->hasCol() && cell->col() == *c) |
| + cells.append(cell); |
| + } |
| + } |
| + section = myTable->sectionBelow(section, SkipEmptySections); |
| + } |
| + return cells; |
| +} |
| + |
| } // namespace blink |