| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 { | 153 { |
| 154 if (!parent()->isLayoutTableCol()) | 154 if (!parent()->isLayoutTableCol()) |
| 155 return nullptr; | 155 return nullptr; |
| 156 | 156 |
| 157 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); | 157 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); |
| 158 ASSERT(parentColumnGroup->isTableColumnGroup()); | 158 ASSERT(parentColumnGroup->isTableColumnGroup()); |
| 159 ASSERT(isTableColumn()); | 159 ASSERT(isTableColumn()); |
| 160 return parentColumnGroup; | 160 return parentColumnGroup; |
| 161 } | 161 } |
| 162 | 162 |
| 163 LayoutTableCol* LayoutTableCol::lastColumnInGroup() const |
| 164 { |
| 165 ASSERT(this->isTableColumnGroupWithColumnChildren()); |
| 166 |
| 167 LayoutTableCol* endCol = nullptr; |
| 168 LayoutTableCol* currentCol = this->nextColumn(); |
| 169 // If column has children, traverse the children to find last. |
| 170 if (this->firstChild()) { |
| 171 while (currentCol && currentCol->enclosingColumnGroup() == this) { |
| 172 endCol = currentCol; |
| 173 currentCol = currentCol->nextColumn(); |
| 174 } |
| 175 } |
| 176 return endCol; |
| 177 } |
| 178 |
| 163 LayoutTableCol* LayoutTableCol::nextColumn() const | 179 LayoutTableCol* LayoutTableCol::nextColumn() const |
| 164 { | 180 { |
| 165 // If |this| is a column-group, the next column is the colgroup's first chil
d column. | 181 // If |this| is a column-group, the next column is the colgroup's first chil
d column. |
| 166 if (LayoutObject* firstChild = this->firstChild()) | 182 if (LayoutObject* firstChild = this->firstChild()) |
| 167 return toLayoutTableCol(firstChild); | 183 return toLayoutTableCol(firstChild); |
| 168 | 184 |
| 169 // Otherwise it's the next column along. | 185 // Otherwise it's the next column along. |
| 170 LayoutObject* next = nextSibling(); | 186 LayoutObject* next = nextSibling(); |
| 171 | 187 |
| 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. | 188 // 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()) | 189 auto p = parent(); |
| 174 next = parent()->nextSibling(); | 190 if (!next && p && p->isLayoutTableCol()) |
| 191 next = p->nextSibling(); |
| 175 | 192 |
| 176 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } | 193 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } |
| 177 | 194 |
| 178 return toLayoutTableCol(next); | 195 return toLayoutTableCol(next); |
| 179 } | 196 } |
| 180 | 197 |
| 181 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa
bleCell*) const | 198 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa
bleCell*) const |
| 182 { | 199 { |
| 183 return style()->borderStart(); | 200 return style()->borderStart(); |
| 184 } | 201 } |
| 185 | 202 |
| 186 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl
eCell*) const | 203 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl
eCell*) const |
| 187 { | 204 { |
| 188 return style()->borderEnd(); | 205 return style()->borderEnd(); |
| 189 } | 206 } |
| 190 | 207 |
| 191 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe
ll* cell) const | 208 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe
ll* cell) const |
| 192 { | 209 { |
| 193 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() + cell->colSpan()).innermostColOrColGroup() == this); | 210 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() + cell->colSpan()).innermostColOrColGroup() == this); |
| 194 return style()->borderStart(); | 211 return style()->borderStart(); |
| 195 } | 212 } |
| 196 | 213 |
| 197 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel
l* cell) const | 214 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel
l* cell) const |
| 198 { | 215 { |
| 199 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() - 1).innermostColOrColGroup() == this); | 216 ASSERT_UNUSED(cell, table()->colElementAtAbsoluteColumn(cell->absoluteColumn
Index() - 1).innermostColOrColGroup() == this); |
| 200 return style()->borderEnd(); | 217 return style()->borderEnd(); |
| 201 } | 218 } |
| 202 | 219 |
| 220 LayoutRect LayoutTableCol::positionForBackgroundDrawing(unsigned absoluteColumnI
ndex) const |
| 221 { |
| 222 |
| 223 // Table spec weirdness alert: |
| 224 // <col> elements need to provide absoluteColumnIndex because |
| 225 // <col> element with span N is treated for display as |
| 226 // N <col> elements with span 1. It does not make sense to talk |
| 227 // about visual <col> position, only about <col> position at a |
| 228 // particular absolute column. |
| 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 Vector<unsigned> LayoutTableCol::getEffectiveColumnIndexes() const |
| 267 { |
| 268 LayoutTable * table = this->table(); |
| 269 Vector<unsigned> indexes; |
| 270 |
| 271 if (!table) |
| 272 return indexes; |
| 273 |
| 274 unsigned lastEffectiveColumn = table->lastEffectiveColumnIndex(); |
| 275 |
| 276 if (isTableColumn()) { |
| 277 unsigned idx = table->colElementToAbsoluteColumn(this); |
| 278 auto span = this->span(); |
| 279 unsigned lastSeenColumn = 0xFFFFFFFF; |
| 280 while (span--) { |
| 281 unsigned effectiveColumn = table->absoluteColumnToEffectiveColumn(id
x++); |
| 282 if (effectiveColumn != lastSeenColumn && effectiveColumn <= lastEffe
ctiveColumn) { |
| 283 indexes.append(effectiveColumn); |
| 284 lastSeenColumn = effectiveColumn; |
| 285 } |
| 286 } |
| 287 } else { // isTableColumnGroup. |
| 288 if (isTableColumnGroupWithColumnChildren()) { |
| 289 LayoutTableCol* currentCol = nullptr; |
| 290 auto lastCol = lastColumnInGroup(); |
| 291 do { |
| 292 currentCol = currentCol ? currentCol->nextColumn() : nextColumn(
); |
| 293 if (currentCol) { |
| 294 auto colIndexes = currentCol->getEffectiveColumnIndexes(); |
| 295 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++
) |
| 296 indexes.append(*c); |
| 297 } |
| 298 } while (currentCol && currentCol != lastCol); |
| 299 } else { // tableColumnGroup with no children. |
| 300 // It extends over 'span' absolute columns. |
| 301 unsigned idx = table->colElementToAbsoluteColumn(this); |
| 302 auto span = this->span(); |
| 303 unsigned lastSeenColumn = 0xFFFFFFFF; |
| 304 while (span--) { |
| 305 unsigned effectiveColumn = table->absoluteColumnToEffectiveColum
n(idx++); |
| 306 if (effectiveColumn != lastSeenColumn && effectiveColumn <= last
EffectiveColumn) { |
| 307 indexes.append(effectiveColumn); |
| 308 lastSeenColumn = effectiveColumn; |
| 309 } |
| 310 } |
| 311 } |
| 312 } |
| 313 return indexes; |
| 314 } |
| 315 |
| 203 } // namespace blink | 316 } // namespace blink |
| OLD | NEW |