Chromium Code Reviews| 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, 2009 Apple Inc. All rights reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
| 8 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 8 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 | 103 |
| 104 bool LayoutTableCol::canHaveChildren() const | 104 bool LayoutTableCol::canHaveChildren() const |
| 105 { | 105 { |
| 106 // Cols cannot have children. This is actually necessary to fix a bug | 106 // Cols cannot have children. This is actually necessary to fix a bug |
| 107 // with libraries.uc.edu, which makes a <p> be a table-column. | 107 // with libraries.uc.edu, which makes a <p> be a table-column. |
| 108 return isTableColumnGroup(); | 108 return isTableColumnGroup(); |
| 109 } | 109 } |
| 110 | 110 |
| 111 LayoutRect LayoutTableCol::clippedOverflowRectForPaintInvalidation(const LayoutB oxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintIn validationState) const | 111 LayoutRect LayoutTableCol::clippedOverflowRectForPaintInvalidation(const LayoutB oxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintIn validationState) const |
| 112 { | 112 { |
| 113 // For now, just paint invalidate the whole table. | 113 LayoutRect r = positionByCellSpan(); |
| 114 // FIXME: Find a better way to do this, e.g., need to paint invalidate all t he cells that we | 114 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, r, paintInvalida tionState); |
| 115 // might have propagated a background color or borders into. | 115 return r; |
| 116 // FIXME: check for paintInvalidationContainer each time here? | |
| 117 | |
| 118 LayoutTable* parentTable = table(); | |
| 119 if (!parentTable) | |
| 120 return LayoutRect(); | |
| 121 return parentTable->clippedOverflowRectForPaintInvalidation(paintInvalidatio nContainer, paintInvalidationState); | |
| 122 } | 116 } |
| 123 | 117 |
| 124 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) | 118 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) |
| 125 { | 119 { |
| 126 // FIXME: Issue paint invalidation of only the rect the image paints in. | 120 // FIXME: Issue paint invalidation of only the rect the image paints in. |
| 127 setShouldDoFullPaintInvalidation(); | 121 // INVALIDATE ALL THE CHILDREN |
| 122 | |
| 123 // This does not work, background does not paint | |
| 124 // table()->setShouldDoFullPaintInvalidation(PaintInvalidationFull); | |
| 125 // This ends up with nothing being painted at all | |
| 126 // 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
| |
| 127 Vector<LayoutTableCell*> cells = getColumnCells(); | |
| 128 for (auto c = cells.begin(); c != cells.end(); c++) | |
| 129 (*c)->setShouldDoFullPaintInvalidation(); | |
| 128 } | 130 } |
| 129 | 131 |
| 130 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() | 132 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() |
| 131 { | 133 { |
| 132 clearPreferredLogicalWidthsDirty(); | 134 clearPreferredLogicalWidthsDirty(); |
| 133 | 135 |
| 134 for (LayoutObject* child = firstChild(); child; child = child->nextSibling() ) | 136 for (LayoutObject* child = firstChild(); child; child = child->nextSibling() ) |
| 135 child->clearPreferredLogicalWidthsDirty(); | 137 child->clearPreferredLogicalWidthsDirty(); |
| 136 } | 138 } |
| 137 | 139 |
| 138 LayoutTable* LayoutTableCol::table() const | 140 LayoutTable* LayoutTableCol::table() const |
| 139 { | 141 { |
| 140 LayoutObject* table = parent(); | 142 LayoutObject* table = parent(); |
| 141 if (table && !table->isTable()) | 143 if (table && !table->isTable()) |
| 142 table = table->parent(); | 144 table = table->parent(); |
| 143 return table && table->isTable() ? toLayoutTable(table) : nullptr; | 145 return table && table->isTable() ? toLayoutTable(table) : nullptr; |
| 144 } | 146 } |
| 145 | 147 |
| 146 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const | 148 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const |
| 147 { | 149 { |
| 148 if (!parent()->isLayoutTableCol()) | 150 if (!parent()->isLayoutTableCol()) |
| 149 return nullptr; | 151 return nullptr; |
| 150 | 152 |
| 151 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); | 153 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); |
| 152 ASSERT(parentColumnGroup->isTableColumnGroup()); | 154 ASSERT(parentColumnGroup->isTableColumnGroup()); |
| 153 ASSERT(isTableColumn()); | 155 ASSERT(isTableColumn()); |
| 154 return parentColumnGroup; | 156 return parentColumnGroup; |
| 155 } | 157 } |
| 156 | 158 |
| 159 LayoutTableCol * LayoutTableCol::lastColumnInGroup() const | |
| 160 { | |
| 161 ASSERT(this->isTableColumnGroup()); | |
| 162 | |
| 163 LayoutTableCol * endCol = 0; | |
| 164 LayoutTableCol * currentCol = this->nextColumn(); | |
| 165 // if column has children, traverse the children to find last | |
| 166 if (this->firstChild()) { | |
| 167 while (currentCol && currentCol->enclosingColumnGroup() == this) { | |
| 168 endCol = currentCol; | |
| 169 currentCol = currentCol->nextColumn(); | |
| 170 } | |
| 171 } else { // otherwise, if we have span, use that to find next child | |
| 172 auto span = this->span(); | |
| 173 endCol = currentCol; | |
| 174 while (--span > 0 && currentCol) { | |
| 175 currentCol = currentCol->nextColumn(); | |
| 176 endCol = currentCol; | |
| 177 } | |
| 178 } | |
| 179 return endCol; | |
| 180 } | |
| 181 | |
| 157 LayoutTableCol* LayoutTableCol::nextColumn() const | 182 LayoutTableCol* LayoutTableCol::nextColumn() const |
| 158 { | 183 { |
| 159 // If |this| is a column-group, the next column is the colgroup's first chil d column. | 184 // If |this| is a column-group, the next column is the colgroup's first chil d column. |
| 160 if (LayoutObject* firstChild = this->firstChild()) | 185 if (LayoutObject* firstChild = this->firstChild()) |
| 161 return toLayoutTableCol(firstChild); | 186 return toLayoutTableCol(firstChild); |
| 162 | 187 |
| 163 // Otherwise it's the next column along. | 188 // Otherwise it's the next column along. |
| 164 LayoutObject* next = nextSibling(); | 189 LayoutObject* next = nextSibling(); |
| 165 | 190 |
| 166 // 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. | 191 // 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. |
| 167 if (!next && parent()->isLayoutTableCol()) | 192 |
| 168 next = parent()->nextSibling(); | 193 auto p = parent(); |
| 194 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.
| |
| 195 next = p->nextSibling(); | |
| 169 | 196 |
| 170 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } | 197 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } |
| 171 | 198 |
| 172 return toLayoutTableCol(next); | 199 return toLayoutTableCol(next); |
| 173 } | 200 } |
| 174 | 201 |
| 175 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa bleCell*) const | 202 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa bleCell*) const |
| 176 { | 203 { |
| 177 return style()->borderStart(); | 204 return style()->borderStart(); |
| 178 } | 205 } |
| 179 | 206 |
| 180 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl eCell*) const | 207 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl eCell*) const |
| 181 { | 208 { |
| 182 return style()->borderEnd(); | 209 return style()->borderEnd(); |
| 183 } | 210 } |
| 184 | 211 |
| 185 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe ll* cell) const | 212 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe ll* cell) const |
| 186 { | 213 { |
| 187 ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()).inner mostColOrColGroup() == this); | 214 ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()).inner mostColOrColGroup() == this); |
| 188 return style()->borderStart(); | 215 return style()->borderStart(); |
| 189 } | 216 } |
| 190 | 217 |
| 191 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel l* cell) const | 218 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel l* cell) const |
| 192 { | 219 { |
| 193 ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1).innermostColOrColGr oup() == this); | 220 ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1).innermostColOrColGr oup() == this); |
| 194 return style()->borderEnd(); | 221 return style()->borderEnd(); |
| 195 } | 222 } |
| 196 | 223 |
| 224 // computes col/colgroup position that only spans cells | |
| 225 LayoutRect LayoutTableCol::positionByCellSpan() const | |
| 226 { | |
| 227 | |
| 228 LayoutTable * myTable = table(); | |
| 229 LayoutRect position; | |
| 230 | |
| 231 if (!myTable) | |
| 232 return position; | |
| 233 | |
| 234 LayoutTableSection* topSection = myTable->topNonEmptySection(); | |
| 235 LayoutTableSection* bottomSection = myTable->bottomNonEmptySection(); | |
| 236 if (!topSection || !bottomSection) | |
| 237 return position; | |
| 238 | |
| 239 unsigned startColumnIndex; | |
| 240 unsigned endColumnIndex; | |
| 241 | |
| 242 if (isTableColumnGroup()) { | |
| 243 // colgroup position | |
| 244 LayoutTableCol * startColumn = nextColumn(); | |
| 245 LayoutTableCol * endColumn = lastColumnInGroup(); | |
| 246 | |
| 247 if (startColumn && endColumn) { | |
| 248 startColumnIndex = myTable->colElementToCol(startColumn); | |
| 249 endColumnIndex = myTable->colElementToCol(endColumn); | |
| 250 } else { | |
| 251 return position; | |
| 252 } | |
| 253 } else { | |
| 254 // col position | |
| 255 startColumnIndex = myTable->colElementToCol(this); | |
| 256 endColumnIndex = std::min(startColumnIndex + span() - 1, bottomSection-> numColumns() - 1); | |
| 257 } | |
| 258 | |
| 259 position = topSection->positionOfIdealCell(0, startColumnIndex); | |
| 260 position.moveBy(topSection->location()); | |
| 261 LayoutRect bottomPosition = bottomSection->positionOfIdealCell(bottomSection ->numRows() - 1, endColumnIndex); | |
| 262 bottomPosition.moveBy(bottomSection->location()); | |
| 263 position.unite(bottomPosition); | |
| 264 return position; | |
| 265 } | |
| 266 | |
| 267 // returns indexes to all columns that span this column | |
| 268 Vector<unsigned> LayoutTableCol::getColumnIndexes() const | |
| 269 { | |
| 270 LayoutTable * myTable = table(); | |
| 271 Vector<unsigned> indexes; | |
| 272 if (isTableColumn()) { | |
| 273 unsigned idx = myTable->colElementToCol(this); | |
| 274 auto span = this->span(); | |
| 275 while (span--) | |
| 276 indexes.append(idx++); | |
| 277 } else { | |
| 278 // isTableColumnGroup | |
| 279 LayoutTableCol* currentCol = nullptr; | |
| 280 auto lastCol = lastColumnInGroup(); | |
| 281 do { | |
| 282 currentCol = currentCol ? currentCol->nextColumn() : nextColumn(); | |
| 283 if (currentCol) { | |
| 284 auto colIndexes = currentCol->getColumnIndexes(); | |
| 285 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) | |
| 286 indexes.append(*c); | |
| 287 } | |
| 288 } while (currentCol && currentCol != lastCol); | |
| 289 } | |
| 290 return indexes; | |
| 291 } | |
| 292 | |
| 293 // returns all cells inside a column | |
| 294 Vector<LayoutTableCell*> LayoutTableCol::getColumnCells() const | |
| 295 { | |
| 296 // enumerate all the columns we need | |
| 297 LayoutTable * myTable = table(); | |
| 298 Vector<LayoutTableCell*> cells; | |
| 299 | |
| 300 if (!myTable) // can't do this before table is laid out | |
| 301 return cells; | |
| 302 | |
| 303 auto colIndexes = getColumnIndexes(); | |
| 304 auto section = myTable->topSection(); | |
| 305 // Get all cells from all columns | |
| 306 while (section) { | |
| 307 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) { | |
| 308 for (unsigned r = 0; r < section->numRows(); r++) { | |
| 309 LayoutTableCell * cell = section->primaryCellAt(r, *c); | |
| 310 if (cell && cell->hasCol() && cell->col() == *c) | |
| 311 cells.append(cell); | |
| 312 } | |
| 313 } | |
| 314 section = myTable->sectionBelow(section, SkipEmptySections); | |
| 315 } | |
| 316 return cells; | |
| 317 } | |
| 318 | |
| 197 } // namespace blink | 319 } // namespace blink |
| OLD | NEW |