RenderRegion* RenderMultiColumnFlowThread::regionAtBlockOffset(const RenderBox* box, LayoutUnit offset, bool extendLastRegion, RegionAutoGenerationPolicy autoGenerationPolicy) { if (!m_inLayout) return RenderFlowThread::regionAtBlockOffset(box, offset, extendLastRegion, autoGenerationPolicy); // Layout in progress. We are calculating the set heights as we speak, so the region range // information is not up-to-date. RenderMultiColumnSet* columnSet = m_lastSetWorkedOn ? m_lastSetWorkedOn : firstMultiColumnSet(); if (!columnSet) { // If there's no set, bail. This multicol is empty or only consists of spanners. There // are no regions. return nullptr; } // The last set worked on is a good guess. But if we're not within the bounds, search for the // right one. if (offset < columnSet->logicalTopInFlowThread()) { do { if (RenderMultiColumnSet* prev = columnSet->previousSiblingMultiColumnSet()) columnSet = prev; else break; } while (offset < columnSet->logicalTopInFlowThread()); } else { while (offset >= columnSet->logicalBottomInFlowThread()) { RenderMultiColumnSet* next = columnSet->nextSiblingMultiColumnSet(); if (!next || !next->hasBeenFlowed()) break; columnSet = next; } } return columnSet; }
void RenderMultiColumnFlowThread::addRegionToThread(RenderRegion* renderRegion) { RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(renderRegion); if (RenderMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) { RenderRegionList::iterator it = m_regionList.find(nextSet); ASSERT(it != m_regionList.end()); m_regionList.insertBefore(it, columnSet); } else m_regionList.add(columnSet); renderRegion->setIsValid(true); }
void RenderMultiColumnFlowThread::setRegionRangeForBox(const RenderBox* box, RenderRegion* startRegion, RenderRegion* endRegion) { // Some column sets may have zero height, which means that two or more sets may start at the // exact same flow thread position, which means that some parts of the code may believe that a // given box lives in sets that it doesn't really live in. Make some adjustments here and // include such sets if they are adjacent to the start and/or end regions. for (RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(startRegion)->previousSiblingMultiColumnSet(); columnSet; columnSet = columnSet->previousSiblingMultiColumnSet()) { if (columnSet->logicalHeightInFlowThread()) break; startRegion = columnSet; } for (RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(startRegion)->nextSiblingMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) { if (columnSet->logicalHeightInFlowThread()) break; endRegion = columnSet; } RenderFlowThread::setRegionRangeForBox(box, startRegion, endRegion); }
void RenderMultiColumnFlowThread::willBeRemovedFromTree() { // Detach all column sets from the flow thread. Cannot destroy them at this point, since they // are siblings of this object, and there may be pointers to this object's sibling somewhere // further up on the call stack. for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) columnSet->detachRegion(); multiColumnBlockFlow()->setMultiColumnFlowThread(nullptr); RenderFlowThread::willBeRemovedFromTree(); }
RenderMultiColumnSet* RenderMultiColumnFlowThread::findSetRendering(RenderObject* renderer) const { for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { if (multicolSet->containsRendererInFlowThread(renderer)) return multicolSet; } return nullptr; }