Title: [96842] trunk
Revision
96842
Author
hy...@apple.com
Date
2011-10-06 12:03:46 -0700 (Thu, 06 Oct 2011)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=69544
        
[CSS3 Regions] Compute the starting and ending regions of a block, so that we can clamp
descendants to those regions. This is preparation for having true overflow in the boxes
in each region, and it's also a performance optimization to reduce the amount of
region walking that the RenderFlowThread is doing.

Add a range map to RenderFlowThread to cache the start/end regions for each box.
        
Amend everyone who calls renderRegionForLine to pass in the box that is making the query.
This box is then used to clamp to start and end regions so that any regions outside of that
range will never be examined.

Reviewed by Dan Bernstein.

Source/WebCore: 

Test: fast/regions/top-overflow-out-of-second-region.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::hasNextPage):
(WebCore::RenderBlock::pageLogicalHeightForOffset):
(WebCore::RenderBlock::pageRemainingLogicalHeightForOffset):
(WebCore::RenderBlock::regionAtBlockOffset):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::~RenderFlowThread):
(WebCore::RenderFlowThread::layout):
(WebCore::RenderFlowThread::renderRegionForLine):
(WebCore::RenderFlowThread::regionLogicalWidthForLine):
(WebCore::RenderFlowThread::regionLogicalHeightForLine):
(WebCore::RenderFlowThread::regionRemainingLogicalHeightForLine):
(WebCore::RenderFlowThread::mapFromFlowToRegion):
(WebCore::RenderFlowThread::removeRenderBoxRegionInfo):
(WebCore::RenderFlowThread::logicalWidthChangedInRegions):
(WebCore::RenderFlowThread::setRegionRangeForBox):
(WebCore::RenderFlowThread::getRegionRangeForBox):
* rendering/RenderFlowThread.h:
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::takeRenderBoxRegionInfo):
(WebCore::RenderRegion::removeRenderBoxRegionInfo):
* rendering/RenderRegion.h:

LayoutTests: 

* fast/regions/top-overflow-out-of-second-region.html: Added.
* platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png: Added.
* platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (96841 => 96842)


--- trunk/LayoutTests/ChangeLog	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/LayoutTests/ChangeLog	2011-10-06 19:03:46 UTC (rev 96842)
@@ -1,3 +1,24 @@
+2011-10-06  David Hyatt  <hy...@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=69544
+        
+        [CSS3 Regions] Compute the starting and ending regions of a block, so that we can clamp
+        descendants to those regions. This is preparation for having true overflow in the boxes
+        in each region, and it's also a performance optimization to reduce the amount of
+        region walking that the RenderFlowThread is doing.
+
+        Add a range map to RenderFlowThread to cache the start/end regions for each box.
+        
+        Amend everyone who calls renderRegionForLine to pass in the box that is making the query.
+        This box is then used to clamp to start and end regions so that any regions outside of that
+        range will never be examined.
+
+        Reviewed by Dan Bernstein.
+
+        * fast/regions/top-overflow-out-of-second-region.html: Added.
+        * platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png: Added.
+        * platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt: Added.
+
 2011-10-06  James Simonsen  <simon...@chromium.org>
 
         [Chromium] Add baselines for new Mac tests. Revert test_expectations breakage.

Added: trunk/LayoutTests/fast/regions/top-overflow-out-of-second-region.html (0 => 96842)


--- trunk/LayoutTests/fast/regions/top-overflow-out-of-second-region.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/top-overflow-out-of-second-region.html	2011-10-06 19:03:46 UTC (rev 96842)
@@ -0,0 +1,63 @@
+<!doctype html>
+
+ <style>
+    #content {
+        -webkit-flow: "flow1";
+        text-align: justify;
+        padding: 5px;
+    }
+    
+    #first-box {
+        border: 1px solid blue;
+        margin-top:100px;
+    }
+    
+    #second-box {
+        margin:-100px auto 0 auto;
+        border: 1px solid green;
+        width:75%
+    }
+    
+    #region1, #region2, #region3 {
+        border: 1px solid black;
+        content: -webkit-from-flow("flow1");
+        display:inline-block
+    }
+
+    #region1 {
+        width: 300px;
+        height: 100px;
+    }
+    
+    #region2 {
+        width: 400px;
+        height: 200px;
+    }
+
+    #container { margin-top:150px }
+
+</style>
+
+<body>
+
+<p>In the test case below, the green block's width should not vary and should use the second region to determine its width.
+It is overflowing upwards out of the blue block, and so the portion that overflows should continue to use the blue block's
+containing block width. The blue block does not exist in region one, so using some hypothetical made-up width is incorrect.
+The overflow should be spilling out of the top of region two. <font color=red>RIGHT NOW THIS TEST HAS INCORRECT RESULTS.</font></p>
+
+<div id="content">
+    <div id="first-box">
+        <div id="second-box">
+            <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
+            region.</P>
+             <p>These lines should all fit to the width of the block in the second region and spill out of the top of the second
+            region.</P>
+        </div>
+    </div>
+</div>
+
+<div id="container">
+    <div id="region1"></div>
+    <div id="region2"></div>
+    <div id="region3"></div>
+</div>

Added: trunk/LayoutTests/platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/fast/regions/top-overflow-out-of-second-region-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt (0 => 96842)


--- trunk/LayoutTests/platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/regions/top-overflow-out-of-second-region-expected.txt	2011-10-06 19:03:46 UTC (rev 96842)
@@ -0,0 +1,46 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x452
+  RenderBlock {HTML} at (0,0) size 800x452
+    RenderBody {BODY} at (8,16) size 784x428
+      RenderBlock {P} at (0,0) size 784x72
+        RenderText {#text} at (0,0) size 779x72
+          text run at (0,0) width 775: "In the test case below, the green block's width should not vary and should use the second region to determine its width. It is"
+          text run at (0,18) width 731: "overflowing upwards out of the blue block, and so the portion that overflows should continue to use the blue block's"
+          text run at (0,36) width 779: "containing block width. The blue block does not exist in region one, so using some hypothetical made-up width is incorrect."
+          text run at (0,54) width 386: "The overflow should be spilling out of the top of region two. "
+        RenderInline {FONT} at (0,0) size 389x18 [color=#FF0000]
+          RenderText {#text} at (386,54) size 389x18
+            text run at (386,54) width 389: "RIGHT NOW THIS TEST HAS INCORRECT RESULTS."
+      RenderBlock {DIV} at (0,222) size 784x206
+        RenderRegion {DIV} at (0,100) size 302x102 [border: (1px solid #000000)]
+        RenderText {#text} at (302,188) size 4x18
+          text run at (302,188) width 4: " "
+        RenderRegion {DIV} at (306,0) size 402x202 [border: (1px solid #000000)]
+        RenderText {#text} at (708,188) size 4x18
+          text run at (708,188) width 4: " "
+        RenderRegion {DIV} at (712,200) size 2x2 [border: (1px solid #000000)]
+        RenderText {#text} at (0,0) size 0x0
+Flow Threads
+  Thread with flow-name 'flow1'
+    layer at (0,0) size 400x300
+      RenderFlowThread at (0,0) size 400x300
+        RenderBlock {DIV} at (0,0) size 400x165
+          RenderBlock {DIV} at (5,100) size 390x60 [border: (1px solid #0000FF)]
+            RenderBlock {DIV} at (48,-99) size 293x158 [border: (1px solid #008000)]
+              RenderBlock {P} at (1,17) size 291x54
+                RenderText {#text} at (0,0) size 291x54
+                  text run at (0,0) width 291: "These lines should all fit to the width of the"
+                  text run at (0,18) width 291: "block in the second region and spill out of the"
+                  text run at (0,36) width 112: "top of the second "
+                  text run at (112,36) width 44: "region."
+              RenderBlock {P} at (1,87) size 291x54
+                RenderText {#text} at (0,0) size 291x54
+                  text run at (0,0) width 291: "These lines should all fit to the width of the"
+                  text run at (0,18) width 291: "block in the second region and spill out of the"
+                  text run at (0,36) width 112: "top of the second "
+                  text run at (112,36) width 44: "region."
+  Regions for flow 'flow1'
+    RenderRegion {DIV} #region1 with index 0
+    RenderRegion {DIV} #region2 with index 0
+    RenderRegion {DIV} #region3 with index 0

Modified: trunk/Source/WebCore/ChangeLog (96841 => 96842)


--- trunk/Source/WebCore/ChangeLog	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/ChangeLog	2011-10-06 19:03:46 UTC (rev 96842)
@@ -1,3 +1,46 @@
+2011-10-06  David Hyatt  <hy...@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=69544
+        
+        [CSS3 Regions] Compute the starting and ending regions of a block, so that we can clamp
+        descendants to those regions. This is preparation for having true overflow in the boxes
+        in each region, and it's also a performance optimization to reduce the amount of
+        region walking that the RenderFlowThread is doing.
+
+        Add a range map to RenderFlowThread to cache the start/end regions for each box.
+        
+        Amend everyone who calls renderRegionForLine to pass in the box that is making the query.
+        This box is then used to clamp to start and end regions so that any regions outside of that
+        range will never be examined.
+
+        Reviewed by Dan Bernstein.
+
+        Test: fast/regions/top-overflow-out-of-second-region.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::layoutBlock):
+        (WebCore::RenderBlock::hasNextPage):
+        (WebCore::RenderBlock::pageLogicalHeightForOffset):
+        (WebCore::RenderBlock::pageRemainingLogicalHeightForOffset):
+        (WebCore::RenderBlock::regionAtBlockOffset):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::~RenderFlowThread):
+        (WebCore::RenderFlowThread::layout):
+        (WebCore::RenderFlowThread::renderRegionForLine):
+        (WebCore::RenderFlowThread::regionLogicalWidthForLine):
+        (WebCore::RenderFlowThread::regionLogicalHeightForLine):
+        (WebCore::RenderFlowThread::regionRemainingLogicalHeightForLine):
+        (WebCore::RenderFlowThread::mapFromFlowToRegion):
+        (WebCore::RenderFlowThread::removeRenderBoxRegionInfo):
+        (WebCore::RenderFlowThread::logicalWidthChangedInRegions):
+        (WebCore::RenderFlowThread::setRegionRangeForBox):
+        (WebCore::RenderFlowThread::getRegionRangeForBox):
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderRegion.cpp:
+        (WebCore::RenderRegion::takeRenderBoxRegionInfo):
+        (WebCore::RenderRegion::removeRenderBoxRegionInfo):
+        * rendering/RenderRegion.h:
+
 2011-10-05  Gavin Barraclough  <barraclo...@apple.com>
 
         Add explicit JSGlobalThis type.

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (96841 => 96842)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2011-10-06 19:03:46 UTC (rev 96842)
@@ -1220,8 +1220,19 @@
     RenderView* renderView = view();
     LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
     
-    if (logicalWidthChangedInRegions())
-        relayoutChildren = true;
+    if (inRenderFlowThread()) {
+        // Regions changing widths can force us to relayout our children.
+        if (logicalWidthChangedInRegions())
+            relayoutChildren = true;
+    
+        // Set our start and end regions. No regions above or below us will be considered by our children. They are
+        // effectively clamped to our region range.
+        LayoutUnit oldHeight =  logicalHeight();
+        setLogicalHeight(INT_MAX / 2); // FIXME: With the eventual refactoring of logical height computation to be region-aware, we can avoid this hack.
+        computeLogicalHeight();
+        enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
+        setLogicalHeight(oldHeight);
+    }
 
     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
     // our current maximal positive and negative margins.  These values are used when we
@@ -1299,6 +1310,9 @@
 
     bool needAnotherLayoutPass = layoutPositionedObjects(relayoutChildren || isRoot());
 
+    if (inRenderFlowThread())
+        enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
+
     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
     computeOverflow(oldClientAfterEdge);
     
@@ -6140,7 +6154,7 @@
 
     // See if we're in the last region.
     LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
-    RenderRegion* region = enclosingRenderFlowThread()->renderRegionForLine(pageOffset, false);
+    RenderRegion* region = enclosingRenderFlowThread()->renderRegionForLine(pageOffset, this);
     if (!region)
         return false;
     if (region->isLastRegion())
@@ -6214,7 +6228,7 @@
     RenderView* renderView = view();
     if (!inRenderFlowThread())
         return renderView->layoutState()->m_pageLogicalHeight;
-    return enclosingRenderFlowThread()->regionLogicalHeightForLine(offset + offsetFromLogicalTopOfFirstPage());
+    return enclosingRenderFlowThread()->regionLogicalHeightForLine(offset + offsetFromLogicalTopOfFirstPage(), this);
 }
 
 LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
@@ -6233,7 +6247,7 @@
         return remainingHeight;
     }
     
-    return enclosingRenderFlowThread()->regionRemainingLogicalHeightForLine(offset, pageBoundaryRule);
+    return enclosingRenderFlowThread()->regionRemainingLogicalHeightForLine(offset, this, pageBoundaryRule);
 }
 
 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
@@ -6427,15 +6441,7 @@
     if (!flowThread || !flowThread->hasValidRegions())
         return 0;
 
-    // FIXME: Technically we need to clamp blockOffset to our border box, since we want any lines or blocks that overflow out of the
-    // logical top or logical bottom to size as though the border box in the first and last regions extended infinitely.
-    // Otherwise the lines are going to size according to the regions they overflow into, which makes no sense when, for example,
-    // the ancestor blocks may not exist in the region either.
-    // The issue with clamping to our border box is we're in the middle of layout, and our actual height hasn't been
-    // determined yet. We'll need to compute our logical height earlier using a passed in intrinsic height of infinity (to detect
-    // max-height clamping), and then cache that result in a global table that can be checked here. If we're not mid-layout, we
-    // can of course just use our border box.
-    return flowThread->renderRegionForLine(offsetFromLogicalTopOfFirstPage() + blockOffset, true);
+    return flowThread->renderRegionForLine(offsetFromLogicalTopOfFirstPage() + blockOffset, this, true);
 }
 
 bool RenderBlock::logicalWidthChangedInRegions() const

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.cpp (96841 => 96842)


--- trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2011-10-06 19:03:46 UTC (rev 96842)
@@ -55,6 +55,12 @@
     setInRenderFlowThread();
 }
 
+RenderFlowThread::~RenderFlowThread()
+{
+    deleteAllValues(m_regionRangeMap);
+    m_regionRangeMap.clear();
+}
+
 PassRefPtr<RenderStyle> RenderFlowThread::createFlowThreadStyle(RenderStyle* parentStyle)
 {
     RefPtr<RenderStyle> newStyle(RenderStyle::create());
@@ -309,6 +315,8 @@
         m_hasValidRegions = false;
         m_regionsHaveUniformLogicalWidth = true;
         m_regionsHaveUniformLogicalHeight = true;
+        deleteAllValues(m_regionRangeMap);
+        m_regionRangeMap.clear();
         LayoutUnit previousRegionLogicalWidth = 0;
         LayoutUnit previousRegionLogicalHeight = 0;
         if (hasRegions()) {
@@ -524,17 +532,29 @@
     }
 }
 
-RenderRegion* RenderFlowThread::renderRegionForLine(LayoutUnit position, bool extendLastRegion) const
+RenderRegion* RenderFlowThread::renderRegionForLine(LayoutUnit position, const RenderBox* box, bool extendLastRegion) const
 {
     ASSERT(!m_regionsInvalidated);
     
+    // We need to clamp blockOffset to our border box, since we want any lines or blocks that overflow out of the
+    // logical top or logical bottom to size as though the border box in the first and last regions extended infinitely.
+    // Otherwise the lines are going to size according to the regions they overflow into, which makes no sense when, for example,
+    // the ancestor blocks may not exist in the region either.
+    RenderRegion* startRegion;
+    RenderRegion* endRegion;
+    if (box == this) {
+        startRegion = firstRegion();
+        endRegion = lastRegion();
+    } else // Clamp to our containing block's set of regions.
+        getRegionRangeForBox(box->containingBlock(), startRegion, endRegion);
+
     // If no region matches the position and extendLastRegion is true, it will return
     // the last valid region. It is similar to auto extending the size of the last region. 
     RenderRegion* lastValidRegion = 0;
     
     // FIXME: The regions are always in order, optimize this search.
     bool useHorizontalWritingMode = isHorizontalWritingMode();
-    for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+    for (RenderRegionList::const_iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
         RenderRegion* region = *iter;
         if (!region->isValid())
             continue;
@@ -544,39 +564,38 @@
 
         LayoutRect regionRect = region->regionRect();
 
-        if ((useHorizontalWritingMode && regionRect.y() <= position && position < regionRect.maxY())
-            || (!useHorizontalWritingMode && regionRect.x() <= position && position < regionRect.maxX()))
+        if ((useHorizontalWritingMode && position < regionRect.maxY()) || (!useHorizontalWritingMode && position < regionRect.maxX()))
             return region;
 
         if (extendLastRegion)
             lastValidRegion = region;
+            
+        if (region == endRegion)
+            break;
     }
 
     return lastValidRegion;
 }
 
-LayoutUnit RenderFlowThread::regionLogicalWidthForLine(LayoutUnit position) const
+LayoutUnit RenderFlowThread::regionLogicalWidthForLine(LayoutUnit position, const RenderBox* box) const
 {
-    const bool extendLastRegion = true;
-    RenderRegion* region = renderRegionForLine(position, extendLastRegion);
+    RenderRegion* region = renderRegionForLine(position, box, true);
     if (!region)
         return contentLogicalWidth();
-
     return isHorizontalWritingMode() ? region->regionRect().width() : region->regionRect().height();
 }
 
-LayoutUnit RenderFlowThread::regionLogicalHeightForLine(LayoutUnit position) const
+LayoutUnit RenderFlowThread::regionLogicalHeightForLine(LayoutUnit position, const RenderBox* box) const
 {
-    RenderRegion* region = renderRegionForLine(position);
+    RenderRegion* region = renderRegionForLine(position, box);
     if (!region)
         return 0;
-
     return isHorizontalWritingMode() ? region->regionRect().height() : region->regionRect().width();
 }
 
-LayoutUnit RenderFlowThread::regionRemainingLogicalHeightForLine(LayoutUnit position, PageBoundaryRule pageBoundaryRule) const
+LayoutUnit RenderFlowThread::regionRemainingLogicalHeightForLine(LayoutUnit position, const RenderBox* box, PageBoundaryRule pageBoundaryRule) const
 {
-    RenderRegion* region = renderRegionForLine(position);
+    RenderRegion* region = renderRegionForLine(position, box);
     if (!region)
         return 0;
 
@@ -603,9 +622,8 @@
     // for now we just take the center of the mapped enclosing box and map it to a region.
     // Note: Using the center in order to avoid rounding errors.
 
-    const bool extendLastRegion = true;
     LayoutPoint center = boxRect.center();
-    RenderRegion* renderRegion = renderRegionForLine(isHorizontalWritingMode() ? center.y() : center.x(), extendLastRegion);
+    RenderRegion* renderRegion = renderRegionForLine(isHorizontalWritingMode() ? center.y() : center.x(), this, true);
     if (!renderRegion)
         return 0;
 
@@ -619,27 +637,35 @@
 
 void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box)
 {
-    // FIXME: Would be nice if we also cached the box's start and end regions so that we didn't have to
-    // walk every single region.
     if (!hasRegions())
         return;
 
-    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+    RenderRegion* startRegion;
+    RenderRegion* endRegion;
+    getRegionRangeForBox(box, startRegion, endRegion);
+    
+    for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
         RenderRegion* region = *iter;
         if (!region->isValid())
             continue;
-        delete region->takeRenderBoxRegionInfo(box);
+        region->removeRenderBoxRegionInfo(box);
+        if (region == endRegion)
+            break;
     }
+    
+    m_regionRangeMap.remove(box);
 }
 
 bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, LayoutUnit offsetFromLogicalTopOfFirstPage)
 {
-    // FIXME: Would be nice if we also cached the box's start and end regions so that we didn't have to
-    // walk every single region.
     if (!hasRegions() || block == this) // Not necessary, since if any region changes, we do a full pagination relayout anyway.
         return false;
 
-    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+    RenderRegion* startRegion;
+    RenderRegion* endRegion;
+    getRegionRangeForBox(block, startRegion, endRegion);
+
+    for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
         RenderRegion* region = *iter;
         
         if (!region->isValid())
@@ -656,6 +682,9 @@
             delete oldInfo;
             return true;
         }
+        
+        if (region == endRegion)
+            break;
     }
     
     return false;
@@ -729,4 +758,47 @@
     return 0;
 }
 
+void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage)
+{
+    // FIXME: Not right for differing writing-modes.
+    RenderRegion* startRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage, box, true);
+    RenderRegion* endRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage + box->logicalHeight(), box, 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;
+            }
+            
+            region->removeRenderBoxRegionInfo(box);
+
+            if (region == range->endRegion())
+                break;
+        }
+        
+        range->setRange(startRegion, endRegion);
+        return;
+    }
+    range = new RenderRegionRange(startRegion, endRegion);
+    m_regionRangeMap.set(box, range);
+}
+
+void RenderFlowThread::getRegionRangeForBox(const RenderBox* box, RenderRegion*& startRegion, RenderRegion*& endRegion) const
+{
+    startRegion = 0;
+    endRegion = 0;
+    RenderRegionRange* range = m_regionRangeMap.get(box);
+    if (!range)
+        return;
+    startRegion = range->startRegion();
+    endRegion = range->endRegion();
+}
+    
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (96841 => 96842)


--- trunk/Source/WebCore/rendering/RenderFlowThread.h	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h	2011-10-06 19:03:46 UTC (rev 96842)
@@ -57,6 +57,7 @@
 class RenderFlowThread: public RenderBlock {
 public:
     RenderFlowThread(Node*, const AtomicString& flowThread);
+    ~RenderFlowThread();
 
     virtual bool isRenderFlowThread() const { return true; }
 
@@ -97,10 +98,10 @@
 
     void repaintRectangleInRegions(const LayoutRect&, bool immediate);
 
-    LayoutUnit regionLogicalWidthForLine(LayoutUnit position) const;
-    LayoutUnit regionLogicalHeightForLine(LayoutUnit position) const;
-    LayoutUnit regionRemainingLogicalHeightForLine(LayoutUnit position, PageBoundaryRule = IncludePageBoundary) const;
-    RenderRegion* renderRegionForLine(LayoutUnit position, bool extendLastRegion = false) const;
+    LayoutUnit regionLogicalWidthForLine(LayoutUnit position, const RenderBox*) const;
+    LayoutUnit regionLogicalHeightForLine(LayoutUnit position, const RenderBox*) const;
+    LayoutUnit regionRemainingLogicalHeightForLine(LayoutUnit position, const RenderBox*, PageBoundaryRule = IncludePageBoundary) const;
+    RenderRegion* renderRegionForLine(LayoutUnit position, const RenderBox*, bool extendLastRegion = false) const;
 
     bool regionsHaveUniformLogicalWidth() const { return m_regionsHaveUniformLogicalWidth; }
     bool regionsHaveUniformLogicalHeight() const { return m_regionsHaveUniformLogicalHeight; }
@@ -117,6 +118,9 @@
     RenderRegion* firstRegion() const;
     RenderRegion* lastRegion() const;
 
+    void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
+    void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
+
 private:
     virtual const char* renderName() const { return "RenderFlowThread"; }
 
@@ -133,6 +137,27 @@
     AtomicString m_flowThread;
     RenderRegionList m_regionList;
 
+    class RenderRegionRange {
+    public:
+        RenderRegionRange(RenderRegion* start, RenderRegion* end)
+        {
+            setRange(start, end);
+        }
+        
+        void setRange(RenderRegion* start, RenderRegion* end)
+        {
+            m_startRegion = start;
+            m_endRegion = end;
+        }
+
+        RenderRegion* startRegion() const { return m_startRegion; }
+        RenderRegion* endRegion() const { return m_endRegion; }
+
+    private:
+        RenderRegion* m_startRegion;
+        RenderRegion* m_endRegion;
+    };
+
     // Observer flow threads have invalid regions that depend on the state of this thread
     // to re-validate their regions. Keeping a set of observer threads make it easy
     // to notify them when a region was removed from this flow.
@@ -143,6 +168,10 @@
     // easy to sort the order of threads layout.
     RenderFlowThreadCountedSet m_layoutBeforeThreadsSet;
 
+    // A maps from RenderBox
+    typedef HashMap<const RenderBox*, RenderRegionRange*> RenderRegionRangeMap;
+    RenderRegionRangeMap m_regionRangeMap;
+
     bool m_hasValidRegions;
     bool m_regionsInvalidated;
     bool m_regionsHaveUniformLogicalWidth;

Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (96841 => 96842)


--- trunk/Source/WebCore/rendering/RenderRegion.cpp	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp	2011-10-06 19:03:46 UTC (rev 96842)
@@ -206,12 +206,14 @@
 
 RenderBoxRegionInfo* RenderRegion::takeRenderBoxRegionInfo(const RenderBox* box)
 {
-    ASSERT(m_isValid && m_flowThread);
-    if (!m_isValid || !m_flowThread)
-        return 0;
     return m_renderBoxRegionInfo.take(box);
 }
 
+void RenderRegion::removeRenderBoxRegionInfo(const RenderBox* box)
+{
+    m_renderBoxRegionInfo.remove(box);
+}
+
 void RenderRegion::deleteAllRenderBoxRegionInfo()
 {
     deleteAllValues(m_renderBoxRegionInfo);

Modified: trunk/Source/WebCore/rendering/RenderRegion.h (96841 => 96842)


--- trunk/Source/WebCore/rendering/RenderRegion.h	2011-10-06 19:00:50 UTC (rev 96841)
+++ trunk/Source/WebCore/rendering/RenderRegion.h	2011-10-06 19:03:46 UTC (rev 96842)
@@ -67,6 +67,8 @@
     RenderBoxRegionInfo* setRenderBoxRegionInfo(const RenderBox*, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset,
         bool containingBlockChainIsInset);
     RenderBoxRegionInfo* takeRenderBoxRegionInfo(const RenderBox*);
+    void removeRenderBoxRegionInfo(const RenderBox*);
+    
     void deleteAllRenderBoxRegionInfo();
 
     LayoutUnit offsetFromLogicalTopOfFirstPage() const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to