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 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(); | |
|
Xianzhu
2016/03/28 00:44:42
Is this change necessary?
atotic1
2016/03/29 17:05:16
I've seen parent() be null while debugging. That's
| |
| 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::positionByCellSpan(unsigned absoluteColumnIndex) cons t | |
| 221 { | |
| 222 LayoutTable * table = this->table(); | |
| 223 LayoutRect position; | |
| 224 | |
| 225 if (!table) | |
| 226 return position; | |
| 227 | |
| 228 LayoutTableSection* topSection = table->topNonEmptySection(); | |
| 229 LayoutTableSection* bottomSection = table->bottomNonEmptySection(); | |
| 230 if (!topSection || !bottomSection) | |
| 231 return position; | |
| 232 | |
| 233 Vector<unsigned> colIndexes = getEffectiveColumnIndexes(); | |
| 234 | |
| 235 if (colIndexes.size() == 0) | |
| 236 return position; | |
| 237 | |
| 238 unsigned startColumnIndex = colIndexes[0]; | |
| 239 unsigned endColumnIndex = colIndexes.last(); | |
| 240 | |
| 241 // Tricky: if <col> has a span, we need to pick a <col> of width 1 | |
| 242 // that starts at absoluteColumnIndex | |
| 243 if (isTableColumn() && colIndexes.size() > 1) { | |
| 244 unsigned wantedEffectiveColumn = table->absoluteColumnToEffectiveColumn( absoluteColumnIndex); | |
| 245 size_t wantedIt = colIndexes.find(wantedEffectiveColumn); | |
| 246 ASSERT(wantedIt != kNotFound); | |
| 247 startColumnIndex = colIndexes[wantedIt]; | |
| 248 endColumnIndex = startColumnIndex; | |
| 249 } | |
| 250 position = topSection->getCellPhysicalPosition(0, startColumnIndex); | |
| 251 position.moveBy(topSection->location()); | |
| 252 LayoutRect bottomPosition = bottomSection->getCellPhysicalPosition(bottomSec tion->numRows() - 1, endColumnIndex); | |
| 253 bottomPosition.moveBy(bottomSection->location()); | |
| 254 position.uniteEvenIfEmpty(bottomPosition); | |
| 255 return position; | |
| 256 } | |
| 257 | |
| 258 Vector<unsigned> LayoutTableCol::getEffectiveColumnIndexes() const | |
| 259 { | |
| 260 LayoutTable * table = this->table(); | |
| 261 Vector<unsigned> indexes; | |
| 262 | |
| 263 if (!table) | |
| 264 return indexes; | |
| 265 | |
| 266 unsigned lastEffectiveColumn = table->lastEffectiveColumnIndex(); | |
| 267 | |
| 268 if (isTableColumn()) { | |
| 269 unsigned idx = table->colElementToAbsoluteColumn(this); | |
| 270 auto span = this->span(); | |
| 271 unsigned lastSeenColumn = 0xFFFFFFFF; | |
| 272 while (span--) { | |
| 273 unsigned effectiveColumn = table->absoluteColumnToEffectiveColumn(id x++); | |
| 274 if (effectiveColumn != lastSeenColumn && effectiveColumn <= lastEffe ctiveColumn) { | |
| 275 indexes.append(effectiveColumn); | |
| 276 lastSeenColumn = effectiveColumn; | |
| 277 } | |
| 278 } | |
| 279 } else { // isTableColumnGroup. | |
| 280 if (isTableColumnGroupWithColumnChildren()) { | |
| 281 LayoutTableCol* currentCol = nullptr; | |
| 282 auto lastCol = lastColumnInGroup(); | |
| 283 do { | |
| 284 currentCol = currentCol ? currentCol->nextColumn() : nextColumn( ); | |
| 285 if (currentCol) { | |
| 286 auto colIndexes = currentCol->getEffectiveColumnIndexes(); | |
| 287 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++ ) | |
| 288 indexes.append(*c); | |
| 289 } | |
| 290 } while (currentCol && currentCol != lastCol); | |
| 291 } else { // tableColumnGroup with no children. | |
| 292 // It extends over 'span' absolute columns. | |
| 293 unsigned idx = table->colElementToAbsoluteColumn(this); | |
| 294 auto span = this->span(); | |
| 295 unsigned lastSeenColumn = 0xFFFFFFFF; | |
| 296 while (span--) { | |
| 297 unsigned effectiveColumn = table->absoluteColumnToEffectiveColum n(idx++); | |
| 298 if (effectiveColumn != lastSeenColumn && effectiveColumn <= last EffectiveColumn) { | |
| 299 indexes.append(effectiveColumn); | |
| 300 lastSeenColumn = effectiveColumn; | |
| 301 } | |
| 302 } | |
| 303 } | |
| 304 } | |
| 305 return indexes; | |
| 306 } | |
| 307 | |
| 203 } // namespace blink | 308 } // namespace blink |
| OLD | NEW |