summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderFlowThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderFlowThread.cpp')
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.cpp131
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));
}