RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren) { if (!m_flowThread) return 0; // Update the dimensions of our regions before we lay out the flow thread. // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions // instead of trying to keep them around. bool shouldInvalidateRegions = false; for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) { if (childBox == m_flowThread) continue; if (relayoutChildren || childBox->needsLayout()) { if (!m_inBalancingPass && childBox->isRenderMultiColumnSet()) toRenderMultiColumnSet(childBox)->prepareForLayout(); shouldInvalidateRegions = true; } } if (shouldInvalidateRegions) m_flowThread->invalidateRegions(); if (relayoutChildren) m_flowThread->setChildNeedsLayout(MarkOnlyThis); setLogicalTopForChild(*m_flowThread, borderAndPaddingBefore()); m_flowThread->layoutIfNeeded(); determineLogicalLeftPositionForChild(*m_flowThread); return m_flowThread; }
void RenderMultiColumnFlowThread::flowThreadDescendantBoxLaidOut(RenderBox* descendant) { if (!descendant->isRenderMultiColumnSpannerPlaceholder()) return; RenderMultiColumnSpannerPlaceholder* placeholder = toRenderMultiColumnSpannerPlaceholder(descendant); RenderBlock* container = placeholder->containingBlock(); for (RenderBox* prev = previousColumnSetOrSpannerSiblingOf(placeholder->spanner()); prev; prev = previousColumnSetOrSpannerSiblingOf(prev)) { if (prev->isRenderMultiColumnSet()) { toRenderMultiColumnSet(prev)->endFlow(container, placeholder->logicalTop()); break; } } for (RenderBox* next = nextColumnSetOrSpannerSiblingOf(placeholder->spanner()); next; next = nextColumnSetOrSpannerSiblingOf(next)) { if (next->isRenderMultiColumnSet()) { m_lastSetWorkedOn = toRenderMultiColumnSet(next); m_lastSetWorkedOn->beginFlow(container); break; } } }
bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher) { if (m_inBalancingPass || !requiresBalancing()) return false; m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout). bool needsRelayout; bool neededRelayout = false; bool firstPass = true; do { // Column heights may change here because of balancing. We may have to do multiple layout // passes, depending on how the contents is fitted to the changed column heights. In most // cases, laying out again twice or even just once will suffice. Sometimes we need more // passes than that, though, but the number of retries should not exceed the number of // columns, unless we have a bug. needsRelayout = false; for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) { RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox); if (multicolSet->calculateBalancedHeight(firstPass)) { multicolSet->setChildNeedsLayout(MarkOnlyThis); needsRelayout = true; } } if (needsRelayout) { // Layout again. Column balancing resulted in a new height. neededRelayout = true; m_flowThread->setChildNeedsLayout(MarkOnlyThis); setChildNeedsLayout(MarkOnlyThis); if (firstPass) statePusher.pop(); layoutBlock(false); } firstPass = false; } while (needsRelayout); m_inBalancingPass = false; return neededRelayout; }