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 |