diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderFlowThread.cpp')
| -rw-r--r-- | Source/WebCore/rendering/RenderFlowThread.cpp | 131 |
1 files changed, 90 insertions, 41 deletions
diff --git a/Source/WebCore/rendering/RenderFlowThread.cpp b/Source/WebCore/rendering/RenderFlowThread.cpp index 967c5d16b..8539a1208 100644 --- a/Source/WebCore/rendering/RenderFlowThread.cpp +++ b/Source/WebCore/rendering/RenderFlowThread.cpp @@ -56,17 +56,6 @@ RenderFlowThread::RenderFlowThread(Node* node, const AtomicString& flowThread) setInRenderFlowThread(); } -void RenderFlowThread::clearRenderRegionRangeMap() -{ - deleteAllValues(m_regionRangeMap); - m_regionRangeMap.clear(); -} - -RenderFlowThread::~RenderFlowThread() -{ - clearRenderRegionRangeMap(); -} - PassRefPtr<RenderStyle> RenderFlowThread::createFlowThreadStyle(RenderStyle* parentStyle) { RefPtr<RenderStyle> newStyle(RenderStyle::create()); @@ -215,7 +204,7 @@ void RenderFlowThread::addRegionToThread(RenderRegion* renderRegion) void RenderFlowThread::removeRegionFromThread(RenderRegion* renderRegion) { ASSERT(renderRegion); - clearRenderRegionRangeMap(); + m_regionRangeMap.clear(); m_regionList.remove(renderRegion); if (renderRegion->parentFlowThread()) { @@ -310,6 +299,27 @@ private: RenderFlowThread* m_renderFlowThread; }; +class CurrentRenderFlowThreadDisabler { + WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadDisabler); +public: + CurrentRenderFlowThreadDisabler(RenderView* view) + : m_view(view) + , m_renderFlowThread(0) + { + m_renderFlowThread = m_view->currentRenderFlowThread(); + if (m_renderFlowThread) + view->setCurrentRenderFlowThread(0); + } + ~CurrentRenderFlowThreadDisabler() + { + if (m_renderFlowThread) + m_view->setCurrentRenderFlowThread(m_renderFlowThread); + } +private: + RenderView* m_view; + RenderFlowThread* m_renderFlowThread; +}; + void RenderFlowThread::layout() { bool regionsChanged = m_regionsInvalidated && everHadLayout(); @@ -318,7 +328,7 @@ void RenderFlowThread::layout() m_hasValidRegions = false; m_regionsHaveUniformLogicalWidth = true; m_regionsHaveUniformLogicalHeight = true; - clearRenderRegionRangeMap(); + m_regionRangeMap.clear(); LayoutUnit previousRegionLogicalWidth = 0; LayoutUnit previousRegionLogicalHeight = 0; if (hasRegions()) { @@ -531,6 +541,10 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect, // Now switch to the region's writing mode coordinate space and let it repaint itself. region->flipForWritingMode(clippedRect); LayoutStateDisabler layoutStateDisabler(view()); // We can't use layout state to repaint, since the region is somewhere else. + + // Can't use currentFlowThread as it possible to have imbricated flow threads and the wrong one could be used, + // so, we let each region figure out the proper enclosing flow thread + CurrentRenderFlowThreadDisabler disabler(view()); region->repaintRectangle(clippedRect, immediate); } } @@ -565,6 +579,14 @@ RenderRegion* RenderFlowThread::renderRegionForLine(LayoutUnit position, bool ex return lastValidRegion; } +LayoutUnit RenderFlowThread::regionLogicalTopForLine(LayoutUnit position) const +{ + RenderRegion* region = renderRegionForLine(position); + if (!region) + return 0; + return isHorizontalWritingMode() ? region->regionRect().y() : region->regionRect().x(); +} + LayoutUnit RenderFlowThread::regionLogicalWidthForLine(LayoutUnit position) const { RenderRegion* region = renderRegionForLine(position, true); @@ -641,7 +663,7 @@ void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box) break; } - delete m_regionRangeMap.take(box); + m_regionRangeMap.remove(box); } bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, LayoutUnit offsetFromLogicalTopOfFirstPage) @@ -661,13 +683,11 @@ bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, La ASSERT(!region->needsLayout()); - RenderBoxRegionInfo* oldInfo = region->takeRenderBoxRegionInfo(block); + OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block); if (!oldInfo) continue; LayoutUnit oldLogicalWidth = oldInfo->logicalWidth(); - delete oldInfo; - RenderBoxRegionInfo* newInfo = block->renderBoxRegionInfo(region, offsetFromLogicalTopOfFirstPage); if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth) return true; @@ -747,48 +767,77 @@ RenderRegion* RenderFlowThread::lastRegion() const return 0; } +void RenderFlowThread::clearRenderBoxCustomStyle(const RenderBox* box, + const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion, + const RenderRegion* newStartRegion, const RenderRegion* newEndRegion) +{ + // Clear the styles for the object in the regions. + // The styles are not cleared for the regions that are contained in both ranges. + bool insideOldRegionRange = false; + bool insideNewRegionRange = false; + for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { + RenderRegion* region = *iter; + + if (oldStartRegion == region) + insideOldRegionRange = true; + if (newStartRegion == region) + insideNewRegionRange = true; + + if (!(insideOldRegionRange && insideNewRegionRange)) + region->clearBoxStyleInRegion(box); + + if (oldEndRegion == region) + insideOldRegionRange = false; + if (newEndRegion == region) + insideNewRegionRange = false; + } +} + void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage) { // FIXME: Not right for differing writing-modes. RenderRegion* startRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage, true); RenderRegion* endRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage + box->logicalHeight(), true); - RenderRegionRange* range = m_regionRangeMap.get(box); - if (range) { - // If nothing changed, just bail. - if (range->startRegion() == startRegion && range->endRegion() == endRegion) - return; - - // Delete any info that we find before our new startRegion and after our new endRegion. - for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { - RenderRegion* region = *iter; - if (region == startRegion) { - iter = m_regionList.find(endRegion); - continue; - } + RenderRegionRangeMap::iterator it = m_regionRangeMap.find(box); + if (it == m_regionRangeMap.end()) { + m_regionRangeMap.set(box, RenderRegionRange(startRegion, endRegion)); + return; + } - region->removeRenderBoxRegionInfo(box); + // If nothing changed, just bail. + RenderRegionRange& range = it->second; + if (range.startRegion() == startRegion && range.endRegion() == endRegion) + return; - if (region == range->endRegion()) - break; + // Delete any info that we find before our new startRegion and after our new endRegion. + for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { + RenderRegion* region = *iter; + if (region == startRegion) { + iter = m_regionList.find(endRegion); + continue; } - range->setRange(startRegion, endRegion); - return; + region->removeRenderBoxRegionInfo(box); + + if (region == range.endRegion()) + break; } - range = new RenderRegionRange(startRegion, endRegion); - m_regionRangeMap.set(box, range); + + clearRenderBoxCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion); + range.setRange(startRegion, endRegion); } void RenderFlowThread::getRegionRangeForBox(const RenderBox* box, RenderRegion*& startRegion, RenderRegion*& endRegion) const { startRegion = 0; endRegion = 0; - RenderRegionRange* range = m_regionRangeMap.get(box); - if (!range) + RenderRegionRangeMap::const_iterator it = m_regionRangeMap.find(box); + if (it == m_regionRangeMap.end()) return; - startRegion = range->startRegion(); - endRegion = range->endRegion(); + const RenderRegionRange& range = it->second; + startRegion = range.startRegion(); + endRegion = range.endRegion(); ASSERT(m_regionList.contains(startRegion) && m_regionList.contains(endRegion)); } |
