diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/rendering/FlowThreadController.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/rendering/FlowThreadController.cpp')
-rw-r--r-- | Source/WebCore/rendering/FlowThreadController.cpp | 181 |
1 files changed, 122 insertions, 59 deletions
diff --git a/Source/WebCore/rendering/FlowThreadController.cpp b/Source/WebCore/rendering/FlowThreadController.cpp index e0f1c6713..44b22bbe1 100644 --- a/Source/WebCore/rendering/FlowThreadController.cpp +++ b/Source/WebCore/rendering/FlowThreadController.cpp @@ -28,11 +28,11 @@ */ #include "config.h" - #include "FlowThreadController.h" #include "NamedFlowCollection.h" #include "RenderFlowThread.h" +#include "RenderLayer.h" #include "RenderNamedFlowThread.h" #include "StyleInheritedData.h" #include "WebKitNamedFlow.h" @@ -40,14 +40,8 @@ namespace WebCore { -PassOwnPtr<FlowThreadController> FlowThreadController::create(RenderView* view) -{ - return adoptPtr(new FlowThreadController(view)); -} - FlowThreadController::FlowThreadController(RenderView* view) : m_view(view) - , m_currentRenderFlowThread(0) , m_isRenderNamedFlowThreadOrderDirty(false) , m_flowThreadsWithAutoLogicalHeightRegions(0) { @@ -57,25 +51,24 @@ FlowThreadController::~FlowThreadController() { } -RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name) +RenderNamedFlowThread& FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name) { if (!m_renderNamedFlowThreadList) - m_renderNamedFlowThreadList = adoptPtr(new RenderNamedFlowThreadList()); + m_renderNamedFlowThreadList = std::make_unique<RenderNamedFlowThreadList>(); else { - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { if (flowRenderer->flowThreadName() == name) - return flowRenderer; + return *flowRenderer; } } - NamedFlowCollection* namedFlows = m_view->document()->namedFlows(); + NamedFlowCollection& namedFlows = m_view->document().namedFlows(); // Sanity check for the absence of a named flow in the "CREATED" state with the same name. - ASSERT(!namedFlows->flowByName(name)); + ASSERT(!namedFlows.flowByName(name)); - RenderNamedFlowThread* flowRenderer = RenderNamedFlowThread::createAnonymous(m_view->document(), namedFlows->ensureFlowWithName(name)); - flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(m_view->style())); + auto flowRenderer = new RenderNamedFlowThread(m_view->document(), RenderFlowThread::createFlowThreadStyle(&m_view->style()), namedFlows.ensureFlowWithName(name)); + flowRenderer->initializeStyle(); m_renderNamedFlowThreadList->add(flowRenderer); // Keep the flow renderer as a child of RenderView. @@ -83,47 +76,39 @@ RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(cons setIsRenderNamedFlowThreadOrderDirty(true); - return flowRenderer; + return *flowRenderer; } void FlowThreadController::styleDidChange() { - RenderStyle* viewStyle = m_view->style(); - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; - flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(viewStyle)); - } + RenderStyle& viewStyle = m_view->style(); + for (auto& flowRenderer : *m_renderNamedFlowThreadList) + flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(&viewStyle)); } void FlowThreadController::layoutRenderNamedFlowThreads() { updateFlowThreadsChainIfNecessary(); - - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) flowRenderer->layoutIfNeeded(); - } } -void FlowThreadController::registerNamedFlowContentNode(Node* contentNode, RenderNamedFlowThread* namedFlow) +void FlowThreadController::registerNamedFlowContentElement(Element& contentElement, RenderNamedFlowThread& namedFlow) { - ASSERT(contentNode && contentNode->isElementNode()); - ASSERT(namedFlow); - ASSERT(!m_mapNamedFlowContentNodes.contains(contentNode)); - ASSERT(!namedFlow->hasContentNode(contentNode)); - m_mapNamedFlowContentNodes.add(contentNode, namedFlow); - namedFlow->registerNamedFlowContentNode(contentNode); + ASSERT(!m_mapNamedFlowContentElement.contains(&contentElement)); + ASSERT(!namedFlow.hasContentElement(contentElement)); + m_mapNamedFlowContentElement.add(&contentElement, &namedFlow); + namedFlow.registerNamedFlowContentElement(contentElement); } -void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode) +void FlowThreadController::unregisterNamedFlowContentElement(Element& contentElement) { - ASSERT(contentNode && contentNode->isElementNode()); - HashMap<const Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode); - ASSERT(it != m_mapNamedFlowContentNodes.end()); + auto it = m_mapNamedFlowContentElement.find(&contentElement); + ASSERT(it != m_mapNamedFlowContentElement.end()); ASSERT(it->value); - ASSERT(it->value->hasContentNode(contentNode)); - it->value->unregisterNamedFlowContentNode(contentNode); - m_mapNamedFlowContentNodes.remove(contentNode); + ASSERT(it->value->hasContentElement(contentElement)); + it->value->unregisterNamedFlowContentElement(contentElement); + m_mapNamedFlowContentElement.remove(&contentElement); } void FlowThreadController::updateFlowThreadsChainIfNecessary() @@ -133,8 +118,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary() // Remove the left-over flow threads. RenderNamedFlowThreadList toRemoveList; - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { if (flowRenderer->isMarkedForDestruction()) toRemoveList.add(flowRenderer); } @@ -142,8 +126,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary() if (toRemoveList.size() > 0) setIsRenderNamedFlowThreadOrderDirty(true); - for (RenderNamedFlowThreadList::iterator iter = toRemoveList.begin(); iter != toRemoveList.end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : toRemoveList) { m_renderNamedFlowThreadList->remove(flowRenderer); flowRenderer->destroy(); } @@ -151,8 +134,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary() if (isRenderNamedFlowThreadOrderDirty()) { // Arrange the thread list according to dependencies. RenderNamedFlowThreadList sortedList; - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { if (sortedList.contains(flowRenderer)) continue; flowRenderer->pushDependencies(sortedList); @@ -167,10 +149,9 @@ bool FlowThreadController::updateFlowThreadsNeedingLayout() { bool needsTwoPassLayout = false; - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { ASSERT(!flowRenderer->needsTwoPhasesLayout()); - flowRenderer->setInConstrainedLayoutPhase(false); + ASSERT(flowRenderer->inMeasureContentLayoutPhase()); if (flowRenderer->needsLayout() && flowRenderer->hasAutoLogicalHeightRegions()) needsTwoPassLayout = true; } @@ -185,8 +166,7 @@ bool FlowThreadController::updateFlowThreadsNeedingTwoStepLayout() { bool needsTwoPassLayout = false; - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { if (flowRenderer->needsTwoPhasesLayout()) { needsTwoPassLayout = true; break; @@ -201,8 +181,7 @@ bool FlowThreadController::updateFlowThreadsNeedingTwoStepLayout() void FlowThreadController::resetFlowThreadsWithAutoHeightRegions() { - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - RenderNamedFlowThread* flowRenderer = *iter; + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { if (flowRenderer->hasAutoLogicalHeightRegions()) { flowRenderer->markAutoLogicalHeightRegionsForLayout(); flowRenderer->invalidateRegions(); @@ -214,7 +193,7 @@ void FlowThreadController::updateFlowThreadsIntoConstrainedPhase() { // Walk the flow chain in reverse order to update the auto-height regions and compute correct sizes for the containing regions. Only after this we can // set the flow in the constrained layout phase. - for (RenderNamedFlowThreadList::reverse_iterator iter = m_renderNamedFlowThreadList->rbegin(); iter != m_renderNamedFlowThreadList->rend(); ++iter) { + for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) { RenderNamedFlowThread* flowRenderer = *iter; ASSERT(!flowRenderer->hasRegions() || flowRenderer->hasValidRegionInfo()); flowRenderer->layoutIfNeeded(); @@ -222,14 +201,98 @@ void FlowThreadController::updateFlowThreadsIntoConstrainedPhase() ASSERT(flowRenderer->needsTwoPhasesLayout()); flowRenderer->markAutoLogicalHeightRegionsForLayout(); } - flowRenderer->setInConstrainedLayoutPhase(true); + flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseConstrained); flowRenderer->clearNeedsTwoPhasesLayout(); } } -bool FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow(const Node* contentNode) const +void FlowThreadController::updateFlowThreadsIntoOverflowPhase() { - return m_mapNamedFlowContentNodes.contains(contentNode); + for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) { + RenderNamedFlowThread* flowRenderer = *iter; + ASSERT(!flowRenderer->hasRegions() || flowRenderer->hasValidRegionInfo()); + ASSERT(!flowRenderer->needsTwoPhasesLayout()); + + // In the overflow computation phase the flow threads start in the constrained phase even though optimizations didn't set the state before. + flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseConstrained); + + flowRenderer->layoutIfNeeded(); + flowRenderer->markRegionsForOverflowLayoutIfNeeded(); + flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseOverflow); + } +} + +void FlowThreadController::updateFlowThreadsIntoMeasureContentPhase() +{ + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { + ASSERT(flowRenderer->inFinalLayoutPhase()); + + flowRenderer->dispatchNamedFlowEvents(); + flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseMeasureContent); + } +} + +void FlowThreadController::updateFlowThreadsIntoFinalPhase() +{ + for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) { + RenderNamedFlowThread* flowRenderer = *iter; + flowRenderer->layoutIfNeeded(); + if (flowRenderer->needsTwoPhasesLayout()) { + flowRenderer->markRegionsForOverflowLayoutIfNeeded(); + flowRenderer->clearNeedsTwoPhasesLayout(); + } + flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseFinal); + } +} + +void FlowThreadController::updateFlowThreadsLayerToRegionMappingsIfNeeded() +{ + for (auto& flowRenderer : *m_renderNamedFlowThreadList) + flowRenderer->updateAllLayerToRegionMappingsIfNeeded(); +} + +void FlowThreadController::updateNamedFlowsLayerListsIfNeeded() +{ + for (auto& flowRenderer : *m_renderNamedFlowThreadList) + flowRenderer->layer()->updateLayerListsIfNeeded(); +} + +static inline bool compareZIndexFlowThreadController(RenderLayer* first, RenderLayer* second) +{ + return first->zIndex() < second->zIndex(); +} + +// Collect the fixed positioned layers that have the named flows as containing block +// These layers are painted and hit-tested starting from RenderView not from regions. +void FlowThreadController::collectFixedPositionedLayers(Vector<RenderLayer*>& fixedPosLayers) const +{ + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { + // If the named flow does not have any regions attached, a fixed element should not be + // displayed even if the fixed element is positioned/sized by the viewport. + if (!flowRenderer->hasRegions()) + continue; + + RenderLayer* flowThreadLayer = flowRenderer->layer(); + if (Vector<RenderLayer*>* negZOrderList = flowThreadLayer->negZOrderList()) { + for (size_t i = 0, size = negZOrderList->size(); i < size; ++i) { + RenderLayer* currLayer = negZOrderList->at(i); + if (currLayer->renderer().style().position() != FixedPosition) + continue; + fixedPosLayers.append(currLayer); + } + } + + if (Vector<RenderLayer*>* posZOrderList = flowThreadLayer->posZOrderList()) { + for (size_t i = 0, size = posZOrderList->size(); i < size; ++i) { + RenderLayer* currLayer = posZOrderList->at(i); + if (currLayer->renderer().style().position() != FixedPosition) + continue; + fixedPosLayers.append(currLayer); + } + } + } + + std::stable_sort(fixedPosLayers.begin(), fixedPosLayers.end(), compareZIndexFlowThreadController); } #ifndef NDEBUG @@ -238,8 +301,8 @@ bool FlowThreadController::isAutoLogicalHeightRegionsCountConsistent() const if (!hasRenderNamedFlowThreads()) return !hasFlowThreadsWithAutoLogicalHeightRegions(); - for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) { - if (!(*iter)->isAutoLogicalHeightRegionsCountConsistent()) + for (auto& flowRenderer : *m_renderNamedFlowThreadList) { + if (!flowRenderer->isAutoLogicalHeightRegionsCountConsistent()) return false; } |