| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 ASSERT(this->location() == LayoutPoint()); | 123 ASSERT(this->location() == LayoutPoint()); |
| 124 | 124 |
| 125 LayoutRect r = table->visualOverflowRect(); | 125 LayoutRect r = table->visualOverflowRect(); |
| 126 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, r, paintInvalida
tionState); | 126 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, r, paintInvalida
tionState); |
| 127 return r; | 127 return r; |
| 128 } | 128 } |
| 129 | 129 |
| 130 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) | 130 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) |
| 131 { | 131 { |
| 132 // FIXME: Issue paint invalidation of only the rect the image paints in. | 132 // FIXME: Issue paint invalidation of only the rect the image paints in. |
| 133 |
| 133 setShouldDoFullPaintInvalidation(); | 134 setShouldDoFullPaintInvalidation(); |
| 135 // This is atotic fix, but I have been unable to find test |
| 136 // case that confirms it. Put it back in once test case is found |
| 137 // Vector<LayoutTableCell*> cells = getColumnCells(); |
| 138 // for (auto c = cells.begin(); c != cells.end(); c++) |
| 139 // (*c)->setShouldDoFullPaintInvalidation(); |
| 134 } | 140 } |
| 135 | 141 |
| 136 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() | 142 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() |
| 137 { | 143 { |
| 138 clearPreferredLogicalWidthsDirty(); | 144 clearPreferredLogicalWidthsDirty(); |
| 139 | 145 |
| 140 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) | 146 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) |
| 141 child->clearPreferredLogicalWidthsDirty(); | 147 child->clearPreferredLogicalWidthsDirty(); |
| 142 } | 148 } |
| 143 | 149 |
| 144 LayoutTable* LayoutTableCol::table() const | 150 LayoutTable* LayoutTableCol::table() const |
| 145 { | 151 { |
| 146 LayoutObject* table = parent(); | 152 LayoutObject* table = parent(); |
| 147 if (table && !table->isTable()) | 153 if (table && !table->isTable()) |
| 148 table = table->parent(); | 154 table = table->parent(); |
| 149 return table && table->isTable() ? toLayoutTable(table) : nullptr; | 155 return table && table->isTable() ? toLayoutTable(table) : nullptr; |
| 150 } | 156 } |
| 151 | 157 |
| 152 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const | 158 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const |
| 153 { | 159 { |
| 154 if (!parent()->isLayoutTableCol()) | 160 if (!parent()->isLayoutTableCol()) |
| 155 return nullptr; | 161 return nullptr; |
| 156 | 162 |
| 157 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); | 163 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); |
| 158 ASSERT(parentColumnGroup->isTableColumnGroup()); | 164 ASSERT(parentColumnGroup->isTableColumnGroup()); |
| 159 ASSERT(isTableColumn()); | 165 ASSERT(isTableColumn()); |
| 160 return parentColumnGroup; | 166 return parentColumnGroup; |
| 161 } | 167 } |
| 162 | 168 |
| 169 |
| 170 LayoutTableCol* LayoutTableCol::lastColumnInGroup() const |
| 171 { |
| 172 ASSERT(this->isTableColumnGroupWithColumnChildren()); |
| 173 |
| 174 LayoutTableCol* endCol = nullptr; |
| 175 LayoutTableCol* currentCol = this->nextColumn(); |
| 176 // If column has children, traverse the children to find last. |
| 177 if (this->firstChild()) { |
| 178 while (currentCol && currentCol->enclosingColumnGroup() == this) { |
| 179 endCol = currentCol; |
| 180 currentCol = currentCol->nextColumn(); |
| 181 } |
| 182 } |
| 183 return endCol; |
| 184 } |
| 185 |
| 163 LayoutTableCol* LayoutTableCol::nextColumn() const | 186 LayoutTableCol* LayoutTableCol::nextColumn() const |
| 164 { | 187 { |
| 165 // If |this| is a column-group, the next column is the colgroup's first chil
d column. | 188 // If |this| is a column-group, the next column is the colgroup's first chil
d column. |
| 166 if (LayoutObject* firstChild = this->firstChild()) | 189 if (LayoutObject* firstChild = this->firstChild()) |
| 167 return toLayoutTableCol(firstChild); | 190 return toLayoutTableCol(firstChild); |
| 168 | 191 |
| 169 // Otherwise it's the next column along. | 192 // Otherwise it's the next column along. |
| 170 LayoutObject* next = nextSibling(); | 193 LayoutObject* next = nextSibling(); |
| 171 | 194 |
| 172 // 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. | 195 // 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. |
| 173 if (!next && parent()->isLayoutTableCol()) | 196 |
| 174 next = parent()->nextSibling(); | 197 auto p = parent(); |
| 198 if (!next && p && p->isLayoutTableCol()) |
| 199 next = p->nextSibling(); |
| 175 | 200 |
| 176 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } | 201 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } |
| 177 | 202 |
| 178 return toLayoutTableCol(next); | 203 return toLayoutTableCol(next); |
| 179 } | 204 } |
| 180 | 205 |
| 181 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa
bleCell*) const | 206 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa
bleCell*) const |
| 182 { | 207 { |
| 183 return style()->borderStart(); | 208 return style()->borderStart(); |
| 184 } | 209 } |
| 185 | 210 |
| 186 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl
eCell*) const | 211 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl
eCell*) const |
| 187 { | 212 { |
| 188 return style()->borderEnd(); | 213 return style()->borderEnd(); |
| 189 } | 214 } |
| 190 | 215 |
| 191 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe
ll* cell) const | 216 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe
ll* cell) const |
| 192 { | 217 { |
| 193 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() + cell->colSpan()).innermostColOrColGroup() == this); | 218 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() + cell->colSpan()).innermostColOrColGroup() == this); |
| 194 return style()->borderStart(); | 219 return style()->borderStart(); |
| 195 } | 220 } |
| 196 | 221 |
| 197 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel
l* cell) const | 222 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel
l* cell) const |
| 198 { | 223 { |
| 199 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() - 1).innermostColOrColGroup() == this); | 224 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() - 1).innermostColOrColGroup() == this); |
| 200 return style()->borderEnd(); | 225 return style()->borderEnd(); |
| 201 } | 226 } |
| 202 | 227 |
| 228 LayoutRect LayoutTableCol::positionByCellSpan(unsigned absoluteColumnIndex) cons
t |
| 229 { |
| 230 LayoutTable * table = this->table(); |
| 231 LayoutRect position; |
| 232 |
| 233 if (!table) |
| 234 return position; |
| 235 |
| 236 LayoutTableSection* topSection = table->topNonEmptySection(); |
| 237 LayoutTableSection* bottomSection = table->bottomNonEmptySection(); |
| 238 if (!topSection || !bottomSection) |
| 239 return position; |
| 240 |
| 241 Vector<unsigned> colIndexes = getEffectiveColumnIndexes(); |
| 242 |
| 243 if (colIndexes.size() == 0) |
| 244 return position; |
| 245 |
| 246 unsigned startColumnIndex = colIndexes[0]; |
| 247 unsigned endColumnIndex = colIndexes.last(); |
| 248 |
| 249 // Tricky: if <col> has a span, we need to pick a <col> of width 1 |
| 250 // that starts at absoluteColumnIndex |
| 251 if (isTableColumn() && colIndexes.size() > 1) { |
| 252 unsigned wantedEffectiveColumn = table->absoluteColumnToEffectiveColumn(
absoluteColumnIndex); |
| 253 size_t wantedIt = colIndexes.find(wantedEffectiveColumn); |
| 254 ASSERT(wantedIt != kNotFound); |
| 255 startColumnIndex = colIndexes[wantedIt]; |
| 256 endColumnIndex = startColumnIndex; |
| 257 } |
| 258 position = topSection->getCellPhysicalPosition(0, startColumnIndex); |
| 259 position.moveBy(topSection->location()); |
| 260 LayoutRect bottomPosition = bottomSection->getCellPhysicalPosition(bottomSec
tion->numRows() - 1, endColumnIndex); |
| 261 bottomPosition.moveBy(bottomSection->location()); |
| 262 position.uniteEvenIfEmpty(bottomPosition); |
| 263 return position; |
| 264 } |
| 265 |
| 266 |
| 267 Vector<unsigned> LayoutTableCol::getEffectiveColumnIndexes() const |
| 268 { |
| 269 LayoutTable * table = this->table(); |
| 270 Vector<unsigned> indexes; |
| 271 |
| 272 if (!table) |
| 273 return indexes; |
| 274 |
| 275 unsigned lastEffectiveColumn = table->lastEffectiveColumnIndex(); |
| 276 |
| 277 if (isTableColumn()) { |
| 278 unsigned idx = table->colElementToAbsoluteColumn(this); |
| 279 auto span = this->span(); |
| 280 unsigned lastSeenColumn = 0xFFFFFFFF; |
| 281 while (span--) { |
| 282 unsigned effectiveColumn = table->absoluteColumnToEffectiveColumn(id
x++); |
| 283 if (effectiveColumn != lastSeenColumn && effectiveColumn <= lastEffe
ctiveColumn) { |
| 284 indexes.append(effectiveColumn); |
| 285 lastSeenColumn = effectiveColumn; |
| 286 } |
| 287 } |
| 288 } else { // isTableColumnGroup |
| 289 if (isTableColumnGroupWithColumnChildren()) { |
| 290 LayoutTableCol* currentCol = nullptr; |
| 291 auto lastCol = lastColumnInGroup(); |
| 292 do { |
| 293 currentCol = currentCol ? currentCol->nextColumn() : nextColumn(
); |
| 294 if (currentCol) { |
| 295 auto colIndexes = currentCol->getEffectiveColumnIndexes(); |
| 296 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++
) |
| 297 indexes.append(*c); |
| 298 } |
| 299 } while (currentCol && currentCol != lastCol); |
| 300 } else { // tableColumnGroup with no children |
| 301 // its covers span columns |
| 302 unsigned idx = table->colElementToAbsoluteColumn(this); |
| 303 auto span = this->span(); |
| 304 unsigned lastSeenColumn = 0xFFFFFFFF; |
| 305 while (span--) { |
| 306 unsigned effectiveColumn = table->absoluteColumnToEffectiveColum
n(idx++); |
| 307 if (effectiveColumn != lastSeenColumn && effectiveColumn <= last
EffectiveColumn) { |
| 308 indexes.append(effectiveColumn); |
| 309 lastSeenColumn = effectiveColumn; |
| 310 } |
| 311 } |
| 312 } |
| 313 } |
| 314 return indexes; |
| 315 } |
| 316 |
| 317 // returns all cells inside a column |
| 318 Vector<LayoutTableCell*> LayoutTableCol::getColumnCells() const |
| 319 { |
| 320 // enumerate all the columns we need |
| 321 LayoutTable * myTable = table(); |
| 322 Vector<LayoutTableCell*> cells; |
| 323 |
| 324 if (!myTable) // can't do this before table is laid out |
| 325 return cells; |
| 326 |
| 327 auto colIndexes = getEffectiveColumnIndexes(); |
| 328 auto section = myTable->topSection(); |
| 329 // Get all cells from all columns |
| 330 while (section) { |
| 331 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) { |
| 332 for (unsigned r = 0; r < section->numRows(); r++) { |
| 333 LayoutTableCell * cell = section->primaryCellAt(r, *c); |
| 334 if (cell && cell->hasSetAbsoluteColumnIndex() && cell->absoluteC
olumnIndex() == *c) |
| 335 cells.append(cell); |
| 336 } |
| 337 } |
| 338 section = myTable->sectionBelow(section, SkipEmptySections); |
| 339 } |
| 340 return cells; |
| 341 } |
| 342 |
| 203 } // namespace blink | 343 } // namespace blink |
| OLD | NEW |