| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 { | 68 { |
| 69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { | 69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { |
| 70 if (sibling->isLayoutMultiColumnSet()) | 70 if (sibling->isLayoutMultiColumnSet()) |
| 71 return toLayoutMultiColumnSet(sibling); | 71 return toLayoutMultiColumnSet(sibling); |
| 72 } | 72 } |
| 73 return 0; | 73 return 0; |
| 74 } | 74 } |
| 75 | 75 |
| 76 static LayoutObject* firstRendererInSet(LayoutMultiColumnSet* multicolSet) | 76 static LayoutObject* firstRendererInSet(LayoutMultiColumnSet* multicolSet) |
| 77 { | 77 { |
| 78 RenderBox* sibling = multicolSet->previousSiblingMultiColumnBox(); | 78 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); |
| 79 if (!sibling) | 79 if (!sibling) |
| 80 return multicolSet->flowThread()->firstChild(); | 80 return multicolSet->flowThread()->firstChild(); |
| 81 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each | 81 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each |
| 82 // of them contains then. | 82 // of them contains then. |
| 83 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); | 83 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); |
| 84 return toLayoutMultiColumnSpannerPlaceholder(sibling)->rendererInFlowThread(
)->nextInPreOrderAfterChildren(multicolSet->flowThread()); | 84 return toLayoutMultiColumnSpannerPlaceholder(sibling)->rendererInFlowThread(
)->nextInPreOrderAfterChildren(multicolSet->flowThread()); |
| 85 } | 85 } |
| 86 | 86 |
| 87 static LayoutObject* lastRendererInSet(LayoutMultiColumnSet* multicolSet) | 87 static LayoutObject* lastRendererInSet(LayoutMultiColumnSet* multicolSet) |
| 88 { | 88 { |
| 89 RenderBox* sibling = multicolSet->nextSiblingMultiColumnBox(); | 89 LayoutBox* sibling = multicolSet->nextSiblingMultiColumnBox(); |
| 90 if (!sibling) | 90 if (!sibling) |
| 91 return 0; // By right we should return lastLeafChild() here, but the cal
ler doesn't care, so just return 0. | 91 return 0; // By right we should return lastLeafChild() here, but the cal
ler doesn't care, so just return 0. |
| 92 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each | 92 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each |
| 93 // of them contains then. | 93 // of them contains then. |
| 94 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); | 94 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); |
| 95 return toLayoutMultiColumnSpannerPlaceholder(sibling)->rendererInFlowThread(
)->previousInPreOrder(multicolSet->flowThread()); | 95 return toLayoutMultiColumnSpannerPlaceholder(sibling)->rendererInFlowThread(
)->previousInPreOrder(multicolSet->flowThread()); |
| 96 } | 96 } |
| 97 | 97 |
| 98 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::findSetRendering(LayoutObject
* renderer) const | 98 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::findSetRendering(LayoutObject
* renderer) const |
| 99 { | 99 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 123 | 123 |
| 124 return 0; | 124 return 0; |
| 125 } | 125 } |
| 126 | 126 |
| 127 LayoutMultiColumnSpannerPlaceholder* LayoutMultiColumnFlowThread::containingColu
mnSpannerPlaceholder(const LayoutObject* descendant) const | 127 LayoutMultiColumnSpannerPlaceholder* LayoutMultiColumnFlowThread::containingColu
mnSpannerPlaceholder(const LayoutObject* descendant) const |
| 128 { | 128 { |
| 129 ASSERT(descendant->isDescendantOf(this)); | 129 ASSERT(descendant->isDescendantOf(this)); |
| 130 | 130 |
| 131 // Before we spend time on searching the ancestry, see if there's a quick wa
y to determine | 131 // Before we spend time on searching the ancestry, see if there's a quick wa
y to determine |
| 132 // whether there might be any spanners at all. | 132 // whether there might be any spanners at all. |
| 133 RenderBox* firstBox = firstMultiColumnBox(); | 133 LayoutBox* firstBox = firstMultiColumnBox(); |
| 134 if (!firstBox || (firstBox == lastMultiColumnBox() && firstBox->isLayoutMult
iColumnSet())) | 134 if (!firstBox || (firstBox == lastMultiColumnBox() && firstBox->isLayoutMult
iColumnSet())) |
| 135 return 0; | 135 return 0; |
| 136 | 136 |
| 137 // We have spanners. See if the renderer in question is one or inside of one
then. | 137 // We have spanners. See if the renderer in question is one or inside of one
then. |
| 138 for (const LayoutObject* ancestor = descendant; ancestor && ancestor != this
; ancestor = ancestor->parent()) { | 138 for (const LayoutObject* ancestor = descendant; ancestor && ancestor != this
; ancestor = ancestor->parent()) { |
| 139 if (LayoutMultiColumnSpannerPlaceholder* placeholder = ancestor->spanner
Placeholder()) | 139 if (LayoutMultiColumnSpannerPlaceholder* placeholder = ancestor->spanner
Placeholder()) |
| 140 return placeholder; | 140 return placeholder; |
| 141 } | 141 } |
| 142 return 0; | 142 return 0; |
| 143 } | 143 } |
| 144 | 144 |
| 145 void LayoutMultiColumnFlowThread::populate() | 145 void LayoutMultiColumnFlowThread::populate() |
| 146 { | 146 { |
| 147 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); | 147 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); |
| 148 ASSERT(!nextSibling()); | 148 ASSERT(!nextSibling()); |
| 149 // Reparent children preceding the flow thread into the flow thread. It's mu
lticol content | 149 // Reparent children preceding the flow thread into the flow thread. It's mu
lticol content |
| 150 // now. At this point there's obviously nothing after the flow thread, but r
enderers (column | 150 // now. At this point there's obviously nothing after the flow thread, but r
enderers (column |
| 151 // sets and spanners) will be inserted there as we insert elements into the
flow thread. | 151 // sets and spanners) will be inserted there as we insert elements into the
flow thread. |
| 152 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), thi
s, true); | 152 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), thi
s, true); |
| 153 } | 153 } |
| 154 | 154 |
| 155 void LayoutMultiColumnFlowThread::evacuateAndDestroy() | 155 void LayoutMultiColumnFlowThread::evacuateAndDestroy() |
| 156 { | 156 { |
| 157 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); | 157 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); |
| 158 m_isBeingEvacuated = true; | 158 m_isBeingEvacuated = true; |
| 159 | 159 |
| 160 // Remove all sets and spanners. | 160 // Remove all sets and spanners. |
| 161 while (RenderBox* columnBox = firstMultiColumnBox()) { | 161 while (LayoutBox* columnBox = firstMultiColumnBox()) { |
| 162 ASSERT(columnBox->isAnonymous()); | 162 ASSERT(columnBox->isAnonymous()); |
| 163 columnBox->destroy(); | 163 columnBox->destroy(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 ASSERT(!previousSibling()); | 166 ASSERT(!previousSibling()); |
| 167 ASSERT(!nextSibling()); | 167 ASSERT(!nextSibling()); |
| 168 | 168 |
| 169 // Finally we can promote all flow thread's children. Before we move them to
the flow thread's | 169 // Finally we can promote all flow thread's children. Before we move them to
the flow thread's |
| 170 // container, we need to unregister the flow thread, so that they aren't jus
t re-added again to | 170 // container, we need to unregister the flow thread, so that they aren't jus
t re-added again to |
| 171 // the flow thread that we're trying to empty. | 171 // the flow thread that we're trying to empty. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 if (!needsLayout()) { | 234 if (!needsLayout()) { |
| 235 // Just before the multicol container (our parent RenderBlockFlow) finis
hes laying out, it | 235 // Just before the multicol container (our parent RenderBlockFlow) finis
hes laying out, it |
| 236 // will call recalculateColumnHeights() on us unconditionally, but we on
ly want that method | 236 // will call recalculateColumnHeights() on us unconditionally, but we on
ly want that method |
| 237 // to do any work if we actually laid out the flow thread. Otherwise, th
e balancing | 237 // to do any work if we actually laid out the flow thread. Otherwise, th
e balancing |
| 238 // machinery would kick in needlessly, and trigger additional layout pas
ses. Furthermore, we | 238 // machinery would kick in needlessly, and trigger additional layout pas
ses. Furthermore, we |
| 239 // actually depend on a proper flowthread layout pass in order to do bal
ancing, since it's | 239 // actually depend on a proper flowthread layout pass in order to do bal
ancing, since it's |
| 240 // flowthread layout that sets up content runs. | 240 // flowthread layout that sets up content runs. |
| 241 return; | 241 return; |
| 242 } | 242 } |
| 243 | 243 |
| 244 for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { | 244 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { |
| 245 if (!columnBox->isLayoutMultiColumnSet()) { | 245 if (!columnBox->isLayoutMultiColumnSet()) { |
| 246 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. | 246 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. |
| 247 m_needsColumnHeightsRecalculation = true; | 247 m_needsColumnHeightsRecalculation = true; |
| 248 continue; | 248 continue; |
| 249 } | 249 } |
| 250 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); | 250 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); |
| 251 if (!m_inBalancingPass) { | 251 if (!m_inBalancingPass) { |
| 252 // This is the initial layout pass. We need to reset the column heig
ht, because contents | 252 // This is the initial layout pass. We need to reset the column heig
ht, because contents |
| 253 // typically have changed. | 253 // typically have changed. |
| 254 columnSet->resetColumnHeight(); | 254 columnSet->resetColumnHeight(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 width = std::max<LayoutUnit>(0, (availableWidth - ((count - 1) * columnG
ap)) / count); | 314 width = std::max<LayoutUnit>(0, (availableWidth - ((count - 1) * columnG
ap)) / count); |
| 315 } else if (!columnStyle->hasAutoColumnWidth() && columnStyle->hasAutoColumnC
ount()) { | 315 } else if (!columnStyle->hasAutoColumnWidth() && columnStyle->hasAutoColumnC
ount()) { |
| 316 count = std::max<LayoutUnit>(1, (availableWidth + columnGap) / (computed
ColumnWidth + columnGap)); | 316 count = std::max<LayoutUnit>(1, (availableWidth + columnGap) / (computed
ColumnWidth + columnGap)); |
| 317 width = ((availableWidth + columnGap) / count) - columnGap; | 317 width = ((availableWidth + columnGap) / count) - columnGap; |
| 318 } else { | 318 } else { |
| 319 count = std::max<LayoutUnit>(std::min<LayoutUnit>(computedColumnCount, (
availableWidth + columnGap) / (computedColumnWidth + columnGap)), 1); | 319 count = std::max<LayoutUnit>(std::min<LayoutUnit>(computedColumnCount, (
availableWidth + columnGap) / (computedColumnWidth + columnGap)), 1); |
| 320 width = ((availableWidth + columnGap) / count) - columnGap; | 320 width = ((availableWidth + columnGap) / count) - columnGap; |
| 321 } | 321 } |
| 322 } | 322 } |
| 323 | 323 |
| 324 void LayoutMultiColumnFlowThread::createAndInsertMultiColumnSet(RenderBox* inser
tBefore) | 324 void LayoutMultiColumnFlowThread::createAndInsertMultiColumnSet(LayoutBox* inser
tBefore) |
| 325 { | 325 { |
| 326 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); | 326 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); |
| 327 LayoutMultiColumnSet* newSet = LayoutMultiColumnSet::createAnonymous(*this,
multicolContainer->styleRef()); | 327 LayoutMultiColumnSet* newSet = LayoutMultiColumnSet::createAnonymous(*this,
multicolContainer->styleRef()); |
| 328 multicolContainer->RenderBlock::addChild(newSet, insertBefore); | 328 multicolContainer->RenderBlock::addChild(newSet, insertBefore); |
| 329 invalidateRegions(); | 329 invalidateRegions(); |
| 330 | 330 |
| 331 // We cannot handle immediate column set siblings (and there's no need for i
t, either). | 331 // We cannot handle immediate column set siblings (and there's no need for i
t, either). |
| 332 // There has to be at least one spanner separating them. | 332 // There has to be at least one spanner separating them. |
| 333 ASSERT(!newSet->previousSiblingMultiColumnBox() || !newSet->previousSiblingM
ultiColumnBox()->isLayoutMultiColumnSet()); | 333 ASSERT(!newSet->previousSiblingMultiColumnBox() || !newSet->previousSiblingM
ultiColumnBox()->isLayoutMultiColumnSet()); |
| 334 ASSERT(!newSet->nextSiblingMultiColumnBox() || !newSet->nextSiblingMultiColu
mnBox()->isLayoutMultiColumnSet()); | 334 ASSERT(!newSet->nextSiblingMultiColumnBox() || !newSet->nextSiblingMultiColu
mnBox()->isLayoutMultiColumnSet()); |
| 335 } | 335 } |
| 336 | 336 |
| 337 void LayoutMultiColumnFlowThread::createAndInsertSpannerPlaceholder(RenderBox* s
panner, RenderBox* insertBefore) | 337 void LayoutMultiColumnFlowThread::createAndInsertSpannerPlaceholder(LayoutBox* s
panner, LayoutBox* insertBefore) |
| 338 { | 338 { |
| 339 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); | 339 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); |
| 340 LayoutMultiColumnSpannerPlaceholder* newPlaceholder = LayoutMultiColumnSpann
erPlaceholder::createAnonymous(multicolContainer->styleRef(), *spanner); | 340 LayoutMultiColumnSpannerPlaceholder* newPlaceholder = LayoutMultiColumnSpann
erPlaceholder::createAnonymous(multicolContainer->styleRef(), *spanner); |
| 341 multicolContainer->RenderBlock::addChild(newPlaceholder, insertBefore); | 341 multicolContainer->RenderBlock::addChild(newPlaceholder, insertBefore); |
| 342 spanner->setSpannerPlaceholder(*newPlaceholder); | 342 spanner->setSpannerPlaceholder(*newPlaceholder); |
| 343 } | 343 } |
| 344 | 344 |
| 345 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const | 345 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const |
| 346 { | 346 { |
| 347 // We assume that we're inside the flow thread. This function is not to be c
alled otherwise. | 347 // We assume that we're inside the flow thread. This function is not to be c
alled otherwise. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 { | 403 { |
| 404 // Detach all column sets from the flow thread. Cannot destroy them at this
point, since they | 404 // Detach all column sets from the flow thread. Cannot destroy them at this
point, since they |
| 405 // are siblings of this object, and there may be pointers to this object's s
ibling somewhere | 405 // are siblings of this object, and there may be pointers to this object's s
ibling somewhere |
| 406 // further up on the call stack. | 406 // further up on the call stack. |
| 407 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col
umnSet = columnSet->nextSiblingMultiColumnSet()) | 407 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col
umnSet = columnSet->nextSiblingMultiColumnSet()) |
| 408 columnSet->detachRegion(); | 408 columnSet->detachRegion(); |
| 409 multiColumnBlockFlow()->resetMultiColumnFlowThread(); | 409 multiColumnBlockFlow()->resetMultiColumnFlowThread(); |
| 410 LayoutFlowThread::willBeRemovedFromTree(); | 410 LayoutFlowThread::willBeRemovedFromTree(); |
| 411 } | 411 } |
| 412 | 412 |
| 413 LayoutUnit LayoutMultiColumnFlowThread::skipColumnSpanner(RenderBox* renderer, L
ayoutUnit logicalTopInFlowThread) | 413 LayoutUnit LayoutMultiColumnFlowThread::skipColumnSpanner(LayoutBox* renderer, L
ayoutUnit logicalTopInFlowThread) |
| 414 { | 414 { |
| 415 ASSERT(renderer->isColumnSpanAll()); | 415 ASSERT(renderer->isColumnSpanAll()); |
| 416 LayoutMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlacehol
der(); | 416 LayoutMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlacehol
der(); |
| 417 LayoutUnit adjustment; | 417 LayoutUnit adjustment; |
| 418 RenderBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox(); | 418 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox(); |
| 419 if (previousColumnBox && previousColumnBox->isLayoutMultiColumnSet()) { | 419 if (previousColumnBox && previousColumnBox->isLayoutMultiColumnSet()) { |
| 420 // Pad flow thread offset to a column boundary, so that any column conte
nt that's supposed | 420 // Pad flow thread offset to a column boundary, so that any column conte
nt that's supposed |
| 421 // to come after the spanner doesn't bleed into the column row preceding
the spanner. | 421 // to come after the spanner doesn't bleed into the column row preceding
the spanner. |
| 422 LayoutMultiColumnSet* previousSet = toLayoutMultiColumnSet(previousColum
nBox); | 422 LayoutMultiColumnSet* previousSet = toLayoutMultiColumnSet(previousColum
nBox); |
| 423 if (previousSet->pageLogicalHeight()) { | 423 if (previousSet->pageLogicalHeight()) { |
| 424 LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTo
pForOffset(logicalTopInFlowThread); | 424 LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTo
pForOffset(logicalTopInFlowThread); |
| 425 if (columnLogicalTopInFlowThread != logicalTopInFlowThread) { | 425 if (columnLogicalTopInFlowThread != logicalTopInFlowThread) { |
| 426 adjustment = columnLogicalTopInFlowThread + previousSet->pageLog
icalHeight() - logicalTopInFlowThread; | 426 adjustment = columnLogicalTopInFlowThread + previousSet->pageLog
icalHeight() - logicalTopInFlowThread; |
| 427 logicalTopInFlowThread += adjustment; | 427 logicalTopInFlowThread += adjustment; |
| 428 } | 428 } |
| 429 } | 429 } |
| 430 previousSet->endFlow(logicalTopInFlowThread); | 430 previousSet->endFlow(logicalTopInFlowThread); |
| 431 } | 431 } |
| 432 RenderBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox(); | 432 LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox(); |
| 433 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) { | 433 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) { |
| 434 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox); | 434 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox); |
| 435 m_lastSetWorkedOn = nextSet; | 435 m_lastSetWorkedOn = nextSet; |
| 436 nextSet->beginFlow(logicalTopInFlowThread); | 436 nextSet->beginFlow(logicalTopInFlowThread); |
| 437 } | 437 } |
| 438 return adjustment; | 438 return adjustment; |
| 439 } | 439 } |
| 440 | 440 |
| 441 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted(LayoutObject*
descendant) | 441 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted(LayoutObject*
descendant) |
| 442 { | 442 { |
| 443 ASSERT(!m_isBeingEvacuated); | 443 ASSERT(!m_isBeingEvacuated); |
| 444 LayoutObject* nextRenderer = descendant->nextInPreOrderAfterChildren(this); | 444 LayoutObject* nextRenderer = descendant->nextInPreOrderAfterChildren(this); |
| 445 // This method ensures that the list of column sets and spanner placeholders
reflects the | 445 // This method ensures that the list of column sets and spanner placeholders
reflects the |
| 446 // multicol content after having inserted a descendant (or descendant subtre
e). See the header | 446 // multicol content after having inserted a descendant (or descendant subtre
e). See the header |
| 447 // file for more information. Go through the subtree that was just inserted
and create column | 447 // file for more information. Go through the subtree that was just inserted
and create column |
| 448 // sets (needed by regular column content) and spanner placeholders (one nee
ded by each spanner) | 448 // sets (needed by regular column content) and spanner placeholders (one nee
ded by each spanner) |
| 449 // where needed. | 449 // where needed. |
| 450 for (LayoutObject* renderer = descendant; renderer; renderer = renderer->nex
tInPreOrder(descendant)) { | 450 for (LayoutObject* renderer = descendant; renderer; renderer = renderer->nex
tInPreOrder(descendant)) { |
| 451 if (containingColumnSpannerPlaceholder(renderer)) | 451 if (containingColumnSpannerPlaceholder(renderer)) |
| 452 continue; // Inside a column spanner. Nothing to do, then. | 452 continue; // Inside a column spanner. Nothing to do, then. |
| 453 if (descendantIsValidColumnSpanner(renderer)) { | 453 if (descendantIsValidColumnSpanner(renderer)) { |
| 454 // This renderer is a spanner, so it needs to establish a spanner pl
aceholder. | 454 // This renderer is a spanner, so it needs to establish a spanner pl
aceholder. |
| 455 RenderBox* insertBefore = 0; | 455 LayoutBox* insertBefore = 0; |
| 456 LayoutMultiColumnSet* setToSplit = 0; | 456 LayoutMultiColumnSet* setToSplit = 0; |
| 457 if (nextRenderer) { | 457 if (nextRenderer) { |
| 458 // The spanner is inserted before something. Figure out what thi
s entails. If the | 458 // The spanner is inserted before something. Figure out what thi
s entails. If the |
| 459 // next renderer is a spanner too, it means that we can simply i
nsert a new spanner | 459 // next renderer is a spanner too, it means that we can simply i
nsert a new spanner |
| 460 // placeholder in front of its placeholder. | 460 // placeholder in front of its placeholder. |
| 461 insertBefore = nextRenderer->spannerPlaceholder(); | 461 insertBefore = nextRenderer->spannerPlaceholder(); |
| 462 if (!insertBefore) { | 462 if (!insertBefore) { |
| 463 // The next renderer isn't a spanner; it's regular column co
ntent. Examine what | 463 // The next renderer isn't a spanner; it's regular column co
ntent. Examine what |
| 464 // comes right before us in the flow thread, then. | 464 // comes right before us in the flow thread, then. |
| 465 LayoutObject* previousRenderer = renderer->previousInPreOrde
r(this); | 465 LayoutObject* previousRenderer = renderer->previousInPreOrde
r(this); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 478 setToSplit = findSetRendering(previousRenderer); | 478 setToSplit = findSetRendering(previousRenderer); |
| 479 ASSERT(setToSplit == findSetRendering(nextRenderer)); | 479 ASSERT(setToSplit == findSetRendering(nextRenderer)); |
| 480 setToSplit->setNeedsLayoutAndFullPaintInvalidation(); | 480 setToSplit->setNeedsLayoutAndFullPaintInvalidation(); |
| 481 insertBefore = setToSplit->nextSiblingMultiColumnBox(); | 481 insertBefore = setToSplit->nextSiblingMultiColumnBox(); |
| 482 // We've found out which set that needs to be split. Now
proceed to | 482 // We've found out which set that needs to be split. Now
proceed to |
| 483 // inserting the spanner placeholder, and then insert a
second column set. | 483 // inserting the spanner placeholder, and then insert a
second column set. |
| 484 } | 484 } |
| 485 } | 485 } |
| 486 ASSERT(setToSplit || insertBefore); | 486 ASSERT(setToSplit || insertBefore); |
| 487 } | 487 } |
| 488 createAndInsertSpannerPlaceholder(toRenderBox(renderer), insertBefor
e); | 488 createAndInsertSpannerPlaceholder(toLayoutBox(renderer), insertBefor
e); |
| 489 if (setToSplit) | 489 if (setToSplit) |
| 490 createAndInsertMultiColumnSet(insertBefore); | 490 createAndInsertMultiColumnSet(insertBefore); |
| 491 continue; | 491 continue; |
| 492 } | 492 } |
| 493 // This renderer is regular column content (i.e. not a spanner). Create
a set if necessary. | 493 // This renderer is regular column content (i.e. not a spanner). Create
a set if necessary. |
| 494 if (nextRenderer) { | 494 if (nextRenderer) { |
| 495 if (LayoutMultiColumnSpannerPlaceholder* placeholder = nextRenderer-
>spannerPlaceholder()) { | 495 if (LayoutMultiColumnSpannerPlaceholder* placeholder = nextRenderer-
>spannerPlaceholder()) { |
| 496 // If inserted right before a spanner, we need to make sure that
there's a set for us there. | 496 // If inserted right before a spanner, we need to make sure that
there's a set for us there. |
| 497 RenderBox* previous = placeholder->previousSiblingMultiColumnBox
(); | 497 LayoutBox* previous = placeholder->previousSiblingMultiColumnBox
(); |
| 498 if (!previous || !previous->isLayoutMultiColumnSet()) | 498 if (!previous || !previous->isLayoutMultiColumnSet()) |
| 499 createAndInsertMultiColumnSet(placeholder); | 499 createAndInsertMultiColumnSet(placeholder); |
| 500 } else { | 500 } else { |
| 501 // Otherwise, since |nextRenderer| isn't a spanner, it has to me
an that there's | 501 // Otherwise, since |nextRenderer| isn't a spanner, it has to me
an that there's |
| 502 // already a set for that content. We can use it for this render
er too. | 502 // already a set for that content. We can use it for this render
er too. |
| 503 ASSERT(findSetRendering(nextRenderer)); | 503 ASSERT(findSetRendering(nextRenderer)); |
| 504 ASSERT(findSetRendering(renderer) == findSetRendering(nextRender
er)); | 504 ASSERT(findSetRendering(renderer) == findSetRendering(nextRender
er)); |
| 505 } | 505 } |
| 506 } else { | 506 } else { |
| 507 // Inserting at the end. Then we just need to make sure that there's
a column set at the end. | 507 // Inserting at the end. Then we just need to make sure that there's
a column set at the end. |
| 508 RenderBox* lastColumnBox = lastMultiColumnBox(); | 508 LayoutBox* lastColumnBox = lastMultiColumnBox(); |
| 509 if (!lastColumnBox || !lastColumnBox->isLayoutMultiColumnSet()) | 509 if (!lastColumnBox || !lastColumnBox->isLayoutMultiColumnSet()) |
| 510 createAndInsertMultiColumnSet(); | 510 createAndInsertMultiColumnSet(); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 } | 513 } |
| 514 | 514 |
| 515 void LayoutMultiColumnFlowThread::flowThreadDescendantWillBeRemoved(LayoutObject
* descendant) | 515 void LayoutMultiColumnFlowThread::flowThreadDescendantWillBeRemoved(LayoutObject
* descendant) |
| 516 { | 516 { |
| 517 // This method ensures that the list of column sets and spanner placeholders
reflects the | 517 // This method ensures that the list of column sets and spanner placeholders
reflects the |
| 518 // multicol content that we'll be left with after removal of a descendant (o
r descendant | 518 // multicol content that we'll be left with after removal of a descendant (o
r descendant |
| 519 // subtree). See the header file for more information. Removing content may
mean that we need to | 519 // subtree). See the header file for more information. Removing content may
mean that we need to |
| 520 // remove column sets and/or spanner placeholders. | 520 // remove column sets and/or spanner placeholders. |
| 521 if (m_isBeingEvacuated) | 521 if (m_isBeingEvacuated) |
| 522 return; | 522 return; |
| 523 bool hadContainingPlaceholder = containingColumnSpannerPlaceholder(descendan
t); | 523 bool hadContainingPlaceholder = containingColumnSpannerPlaceholder(descendan
t); |
| 524 LayoutObject* next; | 524 LayoutObject* next; |
| 525 // Remove spanner placeholders that are no longer needed, and merge column s
ets around them. | 525 // Remove spanner placeholders that are no longer needed, and merge column s
ets around them. |
| 526 for (LayoutObject* renderer = descendant; renderer; renderer = next) { | 526 for (LayoutObject* renderer = descendant; renderer; renderer = next) { |
| 527 LayoutMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlac
eholder(); | 527 LayoutMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlac
eholder(); |
| 528 if (!placeholder) { | 528 if (!placeholder) { |
| 529 next = renderer->nextInPreOrder(descendant); | 529 next = renderer->nextInPreOrder(descendant); |
| 530 continue; | 530 continue; |
| 531 } | 531 } |
| 532 next = renderer->nextInPreOrderAfterChildren(descendant); // It's a span
ner. Its children are of no interest to us. | 532 next = renderer->nextInPreOrderAfterChildren(descendant); // It's a span
ner. Its children are of no interest to us. |
| 533 if (RenderBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox())
{ | 533 if (LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox())
{ |
| 534 RenderBox* previousColumnBox = placeholder->previousSiblingMultiColu
mnBox(); | 534 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColu
mnBox(); |
| 535 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() | 535 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() |
| 536 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSe
t()) { | 536 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSe
t()) { |
| 537 // Need to merge two column sets. | 537 // Need to merge two column sets. |
| 538 nextColumnBox->destroy(); | 538 nextColumnBox->destroy(); |
| 539 previousColumnBox->setNeedsLayout(); | 539 previousColumnBox->setNeedsLayout(); |
| 540 invalidateRegions(); | 540 invalidateRegions(); |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 placeholder->destroy(); | 543 placeholder->destroy(); |
| 544 } | 544 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 } | 668 } |
| 669 | 669 |
| 670 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const | 670 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
| 671 { | 671 { |
| 672 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) | 672 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
| 673 return columnSet->pageLogicalHeight(); | 673 return columnSet->pageLogicalHeight(); |
| 674 return false; | 674 return false; |
| 675 } | 675 } |
| 676 | 676 |
| 677 } | 677 } |
| OLD | NEW |