Changeset 153990 in webkit


Ignore:
Timestamp:
Aug 13, 2013, 12:44:32 AM (12 years ago)
Author:
abucur@adobe.com
Message:

[CSS Regions] Compute correct region ranges for boxes
https://bugs.webkit.org/show_bug.cgi?id=116296

Reviewed by David Hyatt.

Source/WebCore:

The patch extends the region ranges implementation with the following behavior:

  • the range of a box is always included in the range of its containing block (even for floats); this will simplify how overflow

is propagated to the regions and it should later change on a case by case basis.

  • if the range of a box is not correctly estimated before the layout it will be marked for relayout; this is necessary to correctly

position boxes that overflow naturally, like floats.

  • all the boxes have a range now, not only the blocks.
  • regionAtBlockOffset can clamp to a box.
  • an unsplittable box has a region range of a single region, the one where the box top falls into.

When the layout of a child box starts it tries to give an estimate based on the maximal height of the box. After the layout,
if the estimation was wrong, the box is relaid out. For example, if a block with a float is laid out in a region but the float
overflows in the next region a relayout is needed for the float so it can be positioned relative to the containing block
region (this step can be optimized by making a layout pass only for the children that don't have the region range enclosed in the
containing block range).

Tests: fast/regions/bottom-overflow-out-of-first-region-absolute.html

fast/regions/float-pushed-width-change-2.html
fast/regions/scrollable-paragraph-unsplittable.html

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::updateShapesBeforeBlockLayout): Doesn't do anything for regions now.
(WebCore::RenderBlock::updateShapesAfterBlockLayout): Doesn't do anything for regions now.
(WebCore::RenderBlock::relayoutToAvoidWidows): The layout to avoid widows. Widows use the line index to determine the break point,
not the RootLineBox pointer as before. This is necessary to prevent stale pointers in further layouts.
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::layoutBlockChild):
(WebCore::RenderBlock::layoutPositionedObjects):
(WebCore::RenderBlock::markForPaginationRelayoutIfNeeded): Relayout for widows during layoutBlock(). Don't wait to exit the block layout.
(WebCore::RenderBlock::positionNewFloats):
(WebCore::RenderBlock::hasNextPage):
(WebCore::RenderBlock::applyBeforeBreak):
(WebCore::RenderBlock::applyAfterBreak):
(WebCore::RenderBlock::setPageBreak):
(WebCore::RenderBlock::updateMinimumPageHeight):
(WebCore::RenderBlock::regionAtBlockOffset): This function can now clamp at a box.
(WebCore::RenderBlock::computeRegionRangeForBoxChild): Calculate the box region range using the box height.
(WebCore::RenderBlock::estimateRegionRangeForBoxChild): Estimate the box region range using a huge height for the box.
(WebCore::RenderBlock::updateRegionRangeForBoxChild): Determine the final region range of a box.

  • rendering/RenderBlock.h:

(WebCore::RenderBlock::logicalWidthForChild):
(WebCore::RenderBlock::logicalHeightForChild):
(WebCore::RenderBlock::logicalTopForChild):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::layoutInlineChildren):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::clampToStartAndEndRegions):
(WebCore::RenderBox::borderBoxRectInRegion):

  • rendering/RenderBox.h:
  • rendering/RenderDeprecatedFlexibleBox.cpp:

(WebCore::RenderDeprecatedFlexibleBox::layoutBlock):

  • rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::layoutBlock):

  • rendering/RenderFlowThread.cpp:

(WebCore::RenderFlowThread::validateRegions):
(WebCore::RenderFlowThread::regionAtBlockOffset):
(WebCore::RenderFlowThread::adjustedPositionRelativeToOffsetParent):
(WebCore::RenderFlowThread::pageLogicalTopForOffset):
(WebCore::RenderFlowThread::pageLogicalWidthForOffset):
(WebCore::RenderFlowThread::pageLogicalHeightForOffset):
(WebCore::RenderFlowThread::pageRemainingLogicalHeightForOffset):
(WebCore::RenderFlowThread::mapFromFlowToRegion):
(WebCore::RenderFlowThread::logicalWidthChangedInRegionsForBlock):
(WebCore::RenderFlowThread::clearRenderObjectCustomStyle):
(WebCore::RenderFlowThread::clearRenderBoxRegionInfoAndCustomStyle):
(WebCore::RenderFlowThread::setRegionRangeForBox):
(WebCore::RenderFlowThread::applyBreakAfterContent):
(WebCore::RenderFlowThread::addForcedRegionBreak):

  • rendering/RenderFlowThread.h:
  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::layoutBlock):

  • rendering/RenderMultiColumnFlowThread.cpp:

(WebCore::RenderMultiColumnFlowThread::setPageBreak):
(WebCore::RenderMultiColumnFlowThread::updateMinimumPageHeight):

  • rendering/RenderMultiColumnFlowThread.h:

LayoutTests:

Tests for the changes in how region ranges are computed and applied.

  • fast/regions/bottom-overflow-out-of-first-region-absolute-expected.html: Added.
  • fast/regions/bottom-overflow-out-of-first-region-absolute.html: Added.
  • fast/regions/float-pushed-width-change-2-expected.html: Copied from LayoutTests/fast/regions/float-pushed-width-change-expected.html.
  • fast/regions/float-pushed-width-change-2.html: Copied from LayoutTests/fast/regions/float-pushed-width-change.html.
  • fast/regions/float-pushed-width-change-expected.html:
  • fast/regions/float-pushed-width-change.html:
  • fast/regions/scrollable-paragraph-unsplittable-expected.html: Added.
  • fast/regions/scrollable-paragraph-unsplittable.html: Added.
Location:
trunk
Files:
4 added
16 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r153989 r153990  
     12013-08-13  Andrei Bucur  <abucur@adobe.com>
     2
     3        [CSS Regions] Compute correct region ranges for boxes
     4        https://bugs.webkit.org/show_bug.cgi?id=116296
     5
     6        Reviewed by David Hyatt.
     7
     8        Tests for the changes in how region ranges are computed and applied.
     9
     10        * fast/regions/bottom-overflow-out-of-first-region-absolute-expected.html: Added.
     11        * fast/regions/bottom-overflow-out-of-first-region-absolute.html: Added.
     12        * fast/regions/float-pushed-width-change-2-expected.html: Copied from LayoutTests/fast/regions/float-pushed-width-change-expected.html.
     13        * fast/regions/float-pushed-width-change-2.html: Copied from LayoutTests/fast/regions/float-pushed-width-change.html.
     14        * fast/regions/float-pushed-width-change-expected.html:
     15        * fast/regions/float-pushed-width-change.html:
     16        * fast/regions/scrollable-paragraph-unsplittable-expected.html: Added.
     17        * fast/regions/scrollable-paragraph-unsplittable.html: Added.
     18
    1192013-08-13  Zan Dobersek  <zdobersek@igalia.com>
    220
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-2-expected.html

    r153989 r153990  
    22
    33 <style>
    4 
    5     @font-face {
    6         font-family: webkit-ahem;
    7         font-style: normal;
    8         src: url(../../resources/Ahem.ttf);
    9     }
    104   
    115    #float1 {
     
    5044        padding-bottom:10px;
    5145    }
    52        
    53         p.flow1 {
    54                 clear:both;
    55                 margin-bottom: 0px;
    56         }
     46   
     47    p.flow1 {
     48        clear:both;
     49        margin-bottom: 0px;
     50    }
    5751
    58         p.flow2 {
    59                 margin-top: 0px;
    60         }
    61        
     52    p.flow2 {
     53        margin-top: 0px;
     54    }
     55   
    6256</style>
    6357
     
    7670<p>This line of text should not get out of the region.</p>
    7771</div>
    78 
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-2.html

    r153989 r153990  
    22
    33 <style>
    4 
    5    @font-face {
    6         font-family: webkit-ahem;
    7         font-style: normal;
    8         src: url(../../resources/Ahem.ttf);
    9     }
    104
    115    #content {
     
    4741        height: 90px;
    4842    }
     43
     44    #floatcontainer {
     45        height: 84px;
     46    }
    4947</style>
    5048
     
    5553    <div id="first-box">
    5654        <div id="second-box">
    57             <p><img id="float1"><img id="float2">
     55            <p id="floatcontainer"><img id="float1"><img id="float2">
    5856            <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
    59             <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
     57        <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
    6058            <p>This line of text should not get out of the region.</p>
    6159           
  • trunk/LayoutTests/fast/regions/float-pushed-width-change-expected.html

    r133648 r153990  
    22
    33 <style>
    4 
    5     @font-face {
    6         font-family: webkit-ahem;
    7         font-style: normal;
    8         src: url(../../resources/Ahem.ttf);
    9     }
    104   
    115    #float1 {
     
    1913   
    2014    #float2 {
    21         float:right;
     15        margin-top: 30px;
     16        margin-left: -30px;
     17        float:left;
    2218        width:200px;
    2319        height:30px;
     
    6359
    6460<p>In the example below, the green float should be at the top of the first region and on the left. It should spill into region two.
    65 The orange float should be on the right at the top of region two.</p>
     61The orange float should be right aligned under the green float because their containing block is flown only in the first region</p>
    6662
    6763<div id="region1">
     
    7066<div id="region2">
    7167    <img id="float2">
    72     <p class="flow1">This line of text should not get out of the region. This line of text should not get out of the region.</p>
     68    <p class="flow1">This line of text should not get out of the region.</p>
    7369</div>
    7470<div id="region3">
  • trunk/LayoutTests/fast/regions/float-pushed-width-change.html

    r108766 r153990  
    22
    33 <style>
    4 
    5    @font-face {
    6         font-family: webkit-ahem;
    7         font-style: normal;
    8         src: url(../../resources/Ahem.ttf);
    9     }
    104
    115    #content {
     
    5044
    5145<p>In the example below, the green float should be at the top of the first region and on the left. It should spill into region two.
    52 The orange float should be on the right at the top of region two.</p>
     46The orange float should be right aligned under the green float because their containing block is flown only in the first region</p>
    5347
    5448<div id="content">
    5549    <div id="first-box">
    5650        <div id="second-box">
    57             <p><img id="float1"><img id="float2">
    58             <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
     51            <p><img id="float1"><img id="float2"><p/>
     52            <p>This line of text should not get out of the region.</p>
    5953            <p>This line of text should not get out of the region. This line of text should not get out of the region.</p>
    6054            <p>This line of text should not get out of the region.</p>
  • trunk/Source/WebCore/ChangeLog

    r153988 r153990  
     12013-08-13  Andrei Bucur  <abucur@adobe.com>
     2
     3        [CSS Regions] Compute correct region ranges for boxes
     4        https://bugs.webkit.org/show_bug.cgi?id=116296
     5
     6        Reviewed by David Hyatt.
     7
     8        The patch extends the region ranges implementation with the following behavior:
     9        - the range of a box is always included in the range of its containing block (even for floats); this will simplify how overflow
     10        is propagated to the regions and it should later change on a case by case basis.
     11        - if the range of a box is not correctly estimated before the layout it will be marked for relayout; this is necessary to correctly
     12        position boxes that overflow naturally, like floats.
     13        - all the boxes have a range now, not only the blocks.
     14        - regionAtBlockOffset can clamp to a box.
     15        - an unsplittable box has a region range of a single region, the one where the box top falls into.
     16
     17        When the layout of a child box starts it tries to give an estimate based on the maximal height of the box. After the layout,
     18        if the estimation was wrong, the box is relaid out. For example, if a block with a float is laid out in a region but the float
     19        overflows in the next region a relayout is needed for the float so it can be positioned relative to the containing block
     20        region (this step can be optimized by making a layout pass only for the children that don't have the region range enclosed in the
     21        containing block range).
     22
     23        Tests: fast/regions/bottom-overflow-out-of-first-region-absolute.html
     24               fast/regions/float-pushed-width-change-2.html
     25               fast/regions/scrollable-paragraph-unsplittable.html
     26
     27        * rendering/RenderBlock.cpp:
     28        (WebCore::RenderBlock::updateShapesBeforeBlockLayout): Doesn't do anything for regions now.
     29        (WebCore::RenderBlock::updateShapesAfterBlockLayout): Doesn't do anything for regions now.
     30        (WebCore::RenderBlock::relayoutToAvoidWidows): The layout to avoid widows. Widows use the line index to determine the break point,
     31        not the RootLineBox pointer as before. This is necessary to prevent stale pointers in further layouts.
     32        (WebCore::RenderBlock::layoutBlock):
     33        (WebCore::RenderBlock::layoutBlockChild):
     34        (WebCore::RenderBlock::layoutPositionedObjects):
     35        (WebCore::RenderBlock::markForPaginationRelayoutIfNeeded): Relayout for widows during layoutBlock(). Don't wait to exit the block layout.
     36        (WebCore::RenderBlock::positionNewFloats):
     37        (WebCore::RenderBlock::hasNextPage):
     38        (WebCore::RenderBlock::applyBeforeBreak):
     39        (WebCore::RenderBlock::applyAfterBreak):
     40        (WebCore::RenderBlock::setPageBreak):
     41        (WebCore::RenderBlock::updateMinimumPageHeight):
     42        (WebCore::RenderBlock::regionAtBlockOffset): This function can now clamp at a box.
     43        (WebCore::RenderBlock::computeRegionRangeForBoxChild): Calculate the box region range using the box height.
     44        (WebCore::RenderBlock::estimateRegionRangeForBoxChild): Estimate the box region range using a huge height for the box.
     45        (WebCore::RenderBlock::updateRegionRangeForBoxChild): Determine the final region range of a box.
     46        * rendering/RenderBlock.h:
     47        (WebCore::RenderBlock::logicalWidthForChild):
     48        (WebCore::RenderBlock::logicalHeightForChild):
     49        (WebCore::RenderBlock::logicalTopForChild):
     50        * rendering/RenderBlockLineLayout.cpp:
     51        (WebCore::RenderBlock::layoutInlineChildren):
     52        * rendering/RenderBox.cpp:
     53        (WebCore::RenderBox::clampToStartAndEndRegions):
     54        (WebCore::RenderBox::borderBoxRectInRegion):
     55        * rendering/RenderBox.h:
     56        * rendering/RenderDeprecatedFlexibleBox.cpp:
     57        (WebCore::RenderDeprecatedFlexibleBox::layoutBlock):
     58        * rendering/RenderFlexibleBox.cpp:
     59        (WebCore::RenderFlexibleBox::layoutBlock):
     60        * rendering/RenderFlowThread.cpp:
     61        (WebCore::RenderFlowThread::validateRegions):
     62        (WebCore::RenderFlowThread::regionAtBlockOffset):
     63        (WebCore::RenderFlowThread::adjustedPositionRelativeToOffsetParent):
     64        (WebCore::RenderFlowThread::pageLogicalTopForOffset):
     65        (WebCore::RenderFlowThread::pageLogicalWidthForOffset):
     66        (WebCore::RenderFlowThread::pageLogicalHeightForOffset):
     67        (WebCore::RenderFlowThread::pageRemainingLogicalHeightForOffset):
     68        (WebCore::RenderFlowThread::mapFromFlowToRegion):
     69        (WebCore::RenderFlowThread::logicalWidthChangedInRegionsForBlock):
     70        (WebCore::RenderFlowThread::clearRenderObjectCustomStyle):
     71        (WebCore::RenderFlowThread::clearRenderBoxRegionInfoAndCustomStyle):
     72        (WebCore::RenderFlowThread::setRegionRangeForBox):
     73        (WebCore::RenderFlowThread::applyBreakAfterContent):
     74        (WebCore::RenderFlowThread::addForcedRegionBreak):
     75        * rendering/RenderFlowThread.h:
     76        * rendering/RenderGrid.cpp:
     77        (WebCore::RenderGrid::layoutBlock):
     78        * rendering/RenderMultiColumnFlowThread.cpp:
     79        (WebCore::RenderMultiColumnFlowThread::setPageBreak):
     80        (WebCore::RenderMultiColumnFlowThread::updateMinimumPageHeight):
     81        * rendering/RenderMultiColumnFlowThread.h:
     82
    1832013-08-13  Ryosuke Niwa  <rniwa@webkit.org>
    284
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r153814 r153990  
    14811481#endif
    14821482
    1483 bool RenderBlock::updateRegionsAndShapesBeforeChildLayout(RenderFlowThread* flowThread)
     1483bool RenderBlock::updateShapesBeforeBlockLayout()
    14841484{
    14851485#if ENABLE(CSS_SHAPES)
    1486     if (!flowThread && !shapeInsideInfo())
     1486    if (!flowThreadContainingBlock() && !shapeInsideInfo())
    14871487        return shapeInfoRequiresRelayout(this);
    1488 #else
    1489     if (!flowThread)
    1490         return false;
    1491 #endif
    14921488
    14931489    LayoutUnit oldHeight = logicalHeight();
     
    14991495    updateLogicalHeight();
    15001496
    1501 #if ENABLE(CSS_SHAPES)
    15021497    computeShapeSize();
    1503 #endif
    1504 
    1505     // Set our start and end regions. No regions above or below us will be considered by our children. They are
    1506     // effectively clamped to our region range.
    1507     computeRegionRangeForBlock(flowThread);
    15081498
    15091499    setLogicalHeight(oldHeight);
    15101500    setLogicalTop(oldTop);
    15111501
    1512 #if ENABLE(CSS_SHAPES)
    15131502    return shapeInfoRequiresRelayout(this);
    1514 #else
    1515     return false;
    15161503#endif
    15171504}
     
    15281515#endif
    15291516
    1530 void RenderBlock::updateRegionsAndShapesAfterChildLayout(RenderFlowThread* flowThread, bool heightChanged)
     1517void RenderBlock::updateShapesAfterBlockLayout(bool heightChanged)
    15311518{
    15321519#if ENABLE(CSS_SHAPES)
     
    15351522    if (heightChanged && shapeInsideInfo)
    15361523        shapeInsideInfo->dirtyShapeSize();
    1537 #else
    1538     UNUSED_PARAM(heightChanged);
    15391524#endif
    1540     computeRegionRangeForBlock(flowThread);
    1541 }
    1542 
    1543 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
    1544 {
    1545     if (flowThread)
    1546         flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
    15471525}
    15481526
     
    15921570}
    15931571
     1572bool RenderBlock::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
     1573{
     1574    if (!shouldBreakAtLineToAvoidWidow())
     1575        return false;
     1576
     1577    statePusher.pop();
     1578    setEverHadLayout(true);
     1579    layoutBlock(false);
     1580    return true;
     1581}
     1582
    15941583void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
    15951584{
     
    16261615    if (logicalWidthChangedInRegions(flowThread))
    16271616        relayoutChildren = true;
    1628     if (updateRegionsAndShapesBeforeChildLayout(flowThread))
     1617    if (updateShapesBeforeBlockLayout())
    16291618        relayoutChildren = true;
    16301619
     
    16631652        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
    16641653   
    1665     if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
    1666         return;
     1654    if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher) || relayoutToAvoidWidows(statePusher)) {
     1655        ASSERT(!shouldBreakAtLineToAvoidWidow());
     1656        return;
     1657    }
    16671658
    16681659    // Calculate our new height.
     
    16961687    layoutPositionedObjects(relayoutChildren || isRoot());
    16971688
    1698     updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged);
     1689    updateShapesAfterBlockLayout(heightChanged);
    16991690
    17001691    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
     
    26332624    // Go ahead and position the child as though it didn't collapse with the top.
    26342625    setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
     2626    estimateRegionRangeForBoxChild(child);
    26352627
    26362628    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
     
    27092701    }
    27102702
     2703    if (updateRegionRangeForBoxChild(child)) {
     2704        child->setNeedsLayout(true, MarkOnlyThis);
     2705        child->layoutIfNeeded();
     2706    }
     2707
    27112708    // We are no longer at the top of the block if we encounter a non-empty child. 
    27122709    // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
     
    28772874    for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
    28782875        r = *it;
     2876       
     2877        estimateRegionRangeForBoxChild(r);
    28792878
    28802879        // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
     
    29172916            oldLogicalTop = logicalTopForChild(r);
    29182917        }
    2919        
     2918
    29202919        r->layoutIfNeeded();
    29212920
     
    29232922        if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
    29242923            r->setChildNeedsLayout(true, MarkOnlyThis);
     2924            r->layoutIfNeeded();
     2925        }
     2926
     2927        if (updateRegionRangeForBoxChild(r)) {
     2928            r->setNeedsLayout(true, MarkOnlyThis);
    29252929            r->layoutIfNeeded();
    29262930        }
     
    29502954        return;
    29512955
    2952     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()) || shouldBreakAtLineToAvoidWidow())
     2956    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
    29532957        setChildNeedsLayout(true, MarkOnlyThis);
    29542958}
     
    42464250
    42474251        RenderBox* childBox = floatingObject->renderer();
     4252
    42484253        LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
    42494254
     
    42614266        setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
    42624267        setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
     4268
     4269        estimateRegionRangeForBoxChild(childBox);
    42634270
    42644271        LayoutState* layoutState = view()->layoutState();
     
    42944301                if (childBlock)
    42954302                    childBlock->setChildNeedsLayout(true, MarkOnlyThis);
     4303                childBox->layoutIfNeeded();
     4304            }
     4305
     4306            if (updateRegionRangeForBoxChild(childBox)) {
     4307                childBox->setNeedsLayout(true, MarkOnlyThis);
    42964308                childBox->layoutIfNeeded();
    42974309            }
     
    72327244}
    72337245
    7234 void RenderBlock::setBreakAtLineToAvoidWidow(RootInlineBox* lineToBreak)
     7246void RenderBlock::setBreakAtLineToAvoidWidow(int lineToBreak)
    72357247{
    72367248    ASSERT(lineToBreak);
     
    72467258        return;
    72477259    m_rareData->m_shouldBreakAtLineToAvoidWidow = false;
    7248     m_rareData->m_lineBreakToAvoidWidow = 0;
     7260    m_rareData->m_lineBreakToAvoidWidow = -1;
    72497261}
    72507262
     
    74087420    // See if we're in the last region.
    74097421    LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
    7410     RenderRegion* region = flowThread->regionAtBlockOffset(pageOffset, this);
     7422    RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, this);
    74117423    if (!region)
    74127424        return false;
     
    74637475        if (checkRegionBreaks) {
    74647476            LayoutUnit offsetBreakAdjustment = 0;
    7465             if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
     7477            if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
    74667478                return logicalOffset + offsetBreakAdjustment;
    74677479        }
     
    74907502        if (checkRegionBreaks) {
    74917503            LayoutUnit offsetBreakAdjustment = 0;
    7492             if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
     7504            if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
    74937505                return logicalOffset + marginOffset + offsetBreakAdjustment;
    74947506        }
     
    75897601{
    75907602    if (RenderFlowThread* flowThread = flowThreadContainingBlock())
    7591         flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
     7603        flowThread->setPageBreak(this, offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
    75927604}
    75937605
     
    75957607{
    75967608    if (RenderFlowThread* flowThread = flowThreadContainingBlock())
    7597         flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
     7609        flowThread->updateMinimumPageHeight(this, offsetFromLogicalTopOfFirstPage() + offset, minHeight);
    75987610    else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
    75997611        colInfo->updateMinimumColumnHeight(minHeight);
     
    76567668    LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
    76577669
    7658     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineBox)) {
    7659         if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineBox)
     7670    int lineIndex = lineCount(lineBox);
     7671    if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
     7672        if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)
    76607673            clearShouldBreakAtLineToAvoidWidow();
    76617674        // If we have a non-uniform page height, then we have to shift further possibly.
     
    76697682        LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
    76707683        setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
    7671         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineCount(lineBox)))
     7684        if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex))
    76727685            && !isOutOfFlowPositioned() && !isTableCell())
    76737686            setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
     
    78017814        return 0;
    78027815
    7803     return flowThread->regionAtBlockOffset(offsetFromLogicalTopOfFirstPage() + blockOffset, true);
     7816    return flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstPage() + blockOffset, true);
    78047817}
    78057818
     
    78297842}
    78307843
    7831 RenderRegion* RenderBlock::clampToStartAndEndRegions(RenderRegion* region) const
     7844void RenderBlock::computeRegionRangeForBoxChild(const RenderBox* box) const
    78327845{
    78337846    RenderFlowThread* flowThread = flowThreadContainingBlock();
    7834 
    7835     ASSERT(isRenderView() || (region && flowThread));
    7836     if (isRenderView())
    7837         return region;
    7838 
    7839     // We need to clamp to the block, since we want any lines or blocks that overflow out of the
    7840     // logical top or logical bottom of the block to size as though the border box in the first and
    7841     // last regions extended infinitely. Otherwise the lines are going to size according to the regions
    7842     // they overflow into, which makes no sense when this block doesn't exist in |region| at all.
     7847    if (!flowThread || !flowThread->hasRegions())
     7848        return;
     7849
    78437850    RenderRegion* startRegion;
    78447851    RenderRegion* endRegion;
    7845     flowThread->getRegionRangeForBox(this, startRegion, endRegion);
    7846    
    7847     if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent())
    7848         return startRegion;
    7849     if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent())
    7850         return endRegion;
    7851    
    7852     return region;
     7852    LayoutUnit offsetFromLogicalTopOfFirstRegion = box->offsetFromLogicalTopOfFirstPage();
     7853    if (box->isUnsplittableForPagination())
     7854        startRegion = endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
     7855    else {
     7856        startRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
     7857        endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion + logicalHeightForChild(box), true);
     7858    }
     7859
     7860    flowThread->setRegionRangeForBox(box, startRegion, endRegion);
     7861}
     7862
     7863void RenderBlock::estimateRegionRangeForBoxChild(const RenderBox* box) const
     7864{
     7865    RenderFlowThread* flowThread = flowThreadContainingBlock();
     7866    if (!flowThread || !flowThread->hasRegions())
     7867        return;
     7868
     7869    if (box->isUnsplittableForPagination()) {
     7870        computeRegionRangeForBoxChild(box);
     7871        return;
     7872    }
     7873
     7874    LogicalExtentComputedValues estimatedValues;
     7875    box->computeLogicalHeight(RenderFlowThread::maxLogicalHeight(), logicalTopForChild(box), estimatedValues);
     7876
     7877    LayoutUnit offsetFromLogicalTopOfFirstRegion = box->offsetFromLogicalTopOfFirstPage();
     7878    RenderRegion* startRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
     7879    RenderRegion* endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion + estimatedValues.m_extent, true);
     7880
     7881    flowThread->setRegionRangeForBox(box, startRegion, endRegion);
     7882}
     7883
     7884bool RenderBlock::updateRegionRangeForBoxChild(const RenderBox* box) const
     7885{
     7886    RenderFlowThread* flowThread = flowThreadContainingBlock();
     7887    if (!flowThread || !flowThread->hasRegions())
     7888        return false;
     7889
     7890    RenderRegion* startRegion = 0;
     7891    RenderRegion* endRegion = 0;
     7892    flowThread->getRegionRangeForBox(box, startRegion, endRegion);
     7893
     7894    computeRegionRangeForBoxChild(box);
     7895
     7896    RenderRegion* newStartRegion = 0;
     7897    RenderRegion* newEndRegion = 0;
     7898    flowThread->getRegionRangeForBox(box, newStartRegion, newEndRegion);
     7899
     7900    // The region range of the box has changed. Some boxes (e.g floats) may have been positioned assuming
     7901    // a different range.
     7902    // FIXME: Be smarter about this. We don't need to relayout all the time.
     7903    if (newStartRegion != startRegion || newEndRegion != endRegion)
     7904        return true;
     7905
     7906    return false;
    78537907}
    78547908
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r153380 r153990  
    327327    bool shouldBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_shouldBreakAtLineToAvoidWidow; }
    328328    void clearShouldBreakAtLineToAvoidWidow() const;
    329     RootInlineBox* lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : 0; }
    330     void setBreakAtLineToAvoidWidow(RootInlineBox*);
     329    int lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : -1; }
     330    void setBreakAtLineToAvoidWidow(int);
    331331
    332332    // The page logical offset is the object's offset from the top of the page in the page progression
     
    348348    // Accessors for logical width/height and margins in the containing block's block-flow direction.
    349349    enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
    350     LayoutUnit logicalWidthForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->width() : child->height(); }
    351     LayoutUnit logicalHeightForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->height() : child->width(); }
    352     LayoutUnit logicalTopForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->y() : child->x(); }
     350    LayoutUnit logicalWidthForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
     351    LayoutUnit logicalHeightForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->height() : child->width(); }
     352    LayoutUnit logicalTopForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
    353353    void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    354354    void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
     
    593593#endif
    594594
    595     bool updateRegionsAndShapesBeforeChildLayout(RenderFlowThread*);
    596     void updateRegionsAndShapesAfterChildLayout(RenderFlowThread*, bool heightChanged = false);
    597     void computeRegionRangeForBlock(RenderFlowThread*);
     595    bool updateShapesBeforeBlockLayout();
     596    void updateShapesAfterBlockLayout(bool heightChanged = false);
     597    void computeRegionRangeForBoxChild(const RenderBox*) const;
     598
     599    void estimateRegionRangeForBoxChild(const RenderBox*) const;
     600    bool updateRegionRangeForBoxChild(const RenderBox*) const;
    598601
    599602    void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
     
    653656    // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
    654657    virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
     658
     659    bool relayoutToAvoidWidows(LayoutStateMaintainer&);
    655660
    656661    void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild);
     
    11661171    virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const;
    11671172    RenderRegion* regionAtBlockOffset(LayoutUnit) const;
    1168     RenderRegion* clampToStartAndEndRegions(RenderRegion*) const;
    11691173
    11701174protected:
     
    12841288            , m_pageLogicalOffset(0)
    12851289            , m_lineGridBox(0)
    1286             , m_lineBreakToAvoidWidow(0)
     1290            , m_lineBreakToAvoidWidow(-1)
    12871291            , m_shouldBreakAtLineToAvoidWidow(false)
    12881292            , m_discardMarginBefore(false)
     
    13141318        RootInlineBox* m_lineGridBox;
    13151319
    1316         RootInlineBox* m_lineBreakToAvoidWidow;
     1320        int m_lineBreakToAvoidWidow;
    13171321#if ENABLE(CSS_SHAPES)
    13181322        OwnPtr<ShapeInsideInfo> m_shapeInsideInfo;
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r153061 r153990  
    20122012
    20132013            // We now want to break at this line. Remember for next layout and trigger relayout.
    2014             setBreakAtLineToAvoidWidow(lineBox);
     2014            setBreakAtLineToAvoidWidow(lineCount(lineBox));
    20152015            markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
    20162016        }
     
    21502150        for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
    21512151            RenderObject* o = walker.current();
     2152
    21522153            if (!hasInlineChild && o->isInline())
    21532154                hasInlineChild = true;
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r153701 r153990  
    109109}
    110110
     111RenderRegion* RenderBox::clampToStartAndEndRegions(RenderRegion* region) const
     112{
     113    RenderFlowThread* flowThread = flowThreadContainingBlock();
     114
     115    ASSERT(isRenderView() || (region && flowThread));
     116    if (isRenderView())
     117        return region;
     118
     119    // We need to clamp to the block, since we want any lines or blocks that overflow out of the
     120    // logical top or logical bottom of the block to size as though the border box in the first and
     121    // last regions extended infinitely. Otherwise the lines are going to size according to the regions
     122    // they overflow into, which makes no sense when this block doesn't exist in |region| at all.
     123    RenderRegion* startRegion = 0;
     124    RenderRegion* endRegion = 0;
     125    flowThread->getRegionRangeForBox(this, startRegion, endRegion);
     126
     127    if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent())
     128        return startRegion;
     129    if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent())
     130        return endRegion;
     131
     132    return region;
     133}
     134
    111135LayoutRect RenderBox::borderBoxRectInRegion(RenderRegion* region, RenderBoxRegionInfoFlags cacheFlag) const
    112136{
    113137    if (!region)
    114138        return borderBoxRect();
    115    
     139
     140    RenderFlowThread* flowThread = flowThreadContainingBlock();
     141    if (!flowThread)
     142        return borderBoxRect();
     143
     144    RenderRegion* startRegion = 0;
     145    RenderRegion* endRegion = 0;
     146    flowThread->getRegionRangeForBox(this, startRegion, endRegion);
     147
     148    // FIXME: In a perfect world this condition should never happen.
     149    if (!startRegion || !endRegion)
     150        return borderBoxRect();
     151
     152    // FIXME: Once overflow is implemented this assertion needs to be enabled. Right now the overflow content is painted
     153    // in regions outside the box range so the assert is disabled.
     154    // ASSERT(clampToStartAndEndRegions(region) == region);
     155
     156    // FIXME: Remove once boxes are painted inside their region range.
     157    region = clampToStartAndEndRegions(region);
     158
    116159    // Compute the logical width and placement in this region.
    117160    RenderBoxRegionInfo* boxInfo = renderBoxRegionInfo(region, cacheFlag);
     
    29402983                LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage();
    29412984                RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
    2942                 if (cbRegion) {
    2943                     cbRegion = cb->clampToStartAndEndRegions(cbRegion);
     2985                if (cbRegion)
    29442986                    boxInfo = cb->renderBoxRegionInfo(cbRegion);
    2945                 }
    29462987            }
    29472988        } else if (region && flowThread->isHorizontalWritingMode() == containingBlock->isHorizontalWritingMode()) {
     
    31873228        RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
    31883229        if (cbRegion) {
    3189             cbRegion = cb->clampToStartAndEndRegions(cbRegion);
    31903230            RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion);
    31913231            if (boxInfo) {
     
    35063546        RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
    35073547        if (cbRegion) {
    3508             cbRegion = cb->clampToStartAndEndRegions(cbRegion);
    35093548            RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion);
    35103549            if (boxInfo) {
  • trunk/Source/WebCore/rendering/RenderBox.h

    r153380 r153990  
    369369    enum RenderBoxRegionInfoFlags { CacheRenderBoxRegionInfo, DoNotCacheRenderBoxRegionInfo };
    370370    LayoutRect borderBoxRectInRegion(RenderRegion*, RenderBoxRegionInfoFlags = CacheRenderBoxRegionInfo) const;
     371    RenderRegion* clampToStartAndEndRegions(RenderRegion*) const;
    371372    void clearRenderBoxRegionInfo();
    372373    virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const;
  • trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp

    r151997 r153990  
    306306    if (logicalWidthChangedInRegions(flowThread))
    307307        relayoutChildren = true;
    308     if (updateRegionsAndShapesBeforeChildLayout(flowThread))
     308    if (updateShapesBeforeBlockLayout())
    309309        relayoutChildren = true;
    310310
     
    350350    layoutPositionedObjects(relayoutChildren || isRoot());
    351351
    352     updateRegionsAndShapesAfterChildLayout(flowThread);
     352    updateShapesAfterBlockLayout();
    353353
    354354    if (!isFloatingOrOutOfFlowPositioned() && height() == 0) {
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r151997 r153990  
    343343    if (logicalWidthChangedInRegions(flowThread))
    344344        relayoutChildren = true;
    345     if (updateRegionsAndShapesBeforeChildLayout(flowThread))
     345    if (updateShapesBeforeBlockLayout())
    346346        relayoutChildren = true;
    347347
     
    371371    layoutPositionedObjects(relayoutChildren || isRoot());
    372372
    373     updateRegionsAndShapesAfterChildLayout(flowThread);
     373    updateShapesAfterBlockLayout();
    374374
    375375    repaintChildrenDuringLayoutIfMoved(oldChildRects);
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r153814 r153990  
    189189                previousRegionLogicalWidth = regionLogicalWidth;
    190190            }
     191
     192            setRegionRangeForBox(this, m_regionList.first(), m_regionList.last());
    191193        }
    192194    }
     
    391393}
    392394
    393 RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool extendLastRegion, RegionAutoGenerationPolicy autoGenerationPolicy)
     395RenderRegion* RenderFlowThread::regionAtBlockOffset(const RenderBox* clampBox, LayoutUnit offset, bool extendLastRegion, RegionAutoGenerationPolicy autoGenerationPolicy)
    394396{
    395397    ASSERT(!m_regionsInvalidated);
     
    398400        autoGenerateRegionsToBlockOffset(offset);
    399401
     402    if (m_regionList.isEmpty())
     403        return 0;
     404
    400405    if (offset <= 0)
    401         return m_regionList.isEmpty() ? 0 : m_regionList.first();
     406        return clampBox ? clampBox->clampToStartAndEndRegions(m_regionList.first()) : m_regionList.first();
    402407
    403408    RegionSearchAdapter adapter(offset);
     
    406411    // If no region was found, the offset is in the flow thread overflow.
    407412    // The last region will contain the offset if extendLastRegion is set or if the last region is a set.
    408     if (!adapter.result() && !m_regionList.isEmpty() && (extendLastRegion || m_regionList.last()->isRenderRegionSet()))
    409         return m_regionList.last();
    410 
    411     return adapter.result();
     413    if (!adapter.result() && (extendLastRegion || m_regionList.last()->isRenderRegionSet()))
     414        return clampBox ? clampBox->clampToStartAndEndRegions(m_regionList.last()) : m_regionList.last();
     415
     416    RenderRegion* region = adapter.result();
     417    if (!clampBox)
     418        return region;
     419    return region ? clampBox->clampToStartAndEndRegions(region) : 0;
    412420}
    413421   
     
    416424    LayoutPoint referencePoint = startPoint;
    417425   
     426    const RenderBlock* objContainingBlock = boxModelObject.containingBlock();
    418427    // FIXME: This needs to be adapted for different writing modes inside the flow thread.
    419     RenderRegion* startRegion = regionAtBlockOffset(referencePoint.y());
     428    RenderRegion* startRegion = regionAtBlockOffset(objContainingBlock, referencePoint.y());
    420429    if (startRegion) {
    421430        // Take into account the offset coordinates of the region.
     
    437446        // and is no longer valid) and recompute it using the region in which it flows as reference.
    438447        bool wasComputedRelativeToOtherRegion = false;
    439         const RenderBlock* objContainingBlock = boxModelObject.containingBlock();
    440448        while (objContainingBlock && !objContainingBlock->isRenderNamedFlowThread()) {
    441449            // Check if this object is in a different region.
     
    495503LayoutUnit RenderFlowThread::pageLogicalTopForOffset(LayoutUnit offset)
    496504{
    497     RenderRegion* region = regionAtBlockOffset(offset);
     505    RenderRegion* region = regionAtBlockOffset(0, offset, false, AllowRegionAutoGeneration);
    498506    return region ? region->pageLogicalTopForOffset(offset) : LayoutUnit();
    499507}
     
    501509LayoutUnit RenderFlowThread::pageLogicalWidthForOffset(LayoutUnit offset)
    502510{
    503     RenderRegion* region = regionAtBlockOffset(offset, true);
     511    RenderRegion* region = regionAtBlockOffset(0, offset, true, AllowRegionAutoGeneration);
    504512    return region ? region->pageLogicalWidth() : contentLogicalWidth();
    505513}
     
    507515LayoutUnit RenderFlowThread::pageLogicalHeightForOffset(LayoutUnit offset)
    508516{
    509     RenderRegion* region = regionAtBlockOffset(offset);
     517    RenderRegion* region = regionAtBlockOffset(0, offset, false, AllowRegionAutoGeneration);
    510518    if (!region)
    511519        return 0;
     
    516524LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule)
    517525{
    518     RenderRegion* region = regionAtBlockOffset(offset);
     526    RenderRegion* region = regionAtBlockOffset(0, offset, false, AllowRegionAutoGeneration);
    519527    if (!region)
    520528        return 0;
     
    545553
    546554    LayoutPoint center = boxRect.center();
    547     RenderRegion* renderRegion = const_cast<RenderFlowThread*>(this)->regionAtBlockOffset(isHorizontalWritingMode() ? center.y() : center.x(), true, DisallowRegionAutoGeneration);
     555    RenderRegion* renderRegion = const_cast<RenderFlowThread*>(this)->regionAtBlockOffset(this, isHorizontalWritingMode() ? center.y() : center.x(), true, DisallowRegionAutoGeneration);
    548556    if (!renderRegion)
    549557        return 0;
     
    595603        return false;
    596604
     605    RenderRegionRangeMap::iterator it = m_regionRangeMap.find(block);
     606    if (it == m_regionRangeMap.end())
     607        return false;
     608
     609    RenderRegionRange& range = it->value;
     610    bool rangeInvalidated = range.rangeInvalidated();
     611    range.clearRangeInvalidated();
     612
    597613    RenderRegion* startRegion;
    598614    RenderRegion* endRegion;
    599615    getRegionRangeForBox(block, startRegion, endRegion);
    600616
    601     // When the region chain is invalidated the box information is discarded so we must assume the width has changed.
    602     if (m_pageLogicalSizeChanged && !startRegion)
    603         return true;
    604 
    605617    // Not necessary for the flow thread, since we already computed the correct info for it.
     618    // If the regions have changed invalidate the children.
    606619    if (block == this)
    607         return false;
     620        return m_pageLogicalSizeChanged;
    608621
    609622    for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
     
    611624        ASSERT(!region->needsLayout() || region->isRenderRegionSet());
    612625
     626        // We have no information computed for this region so we need to do it.
    613627        OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block);
    614628        if (!oldInfo)
    615             continue;
     629            return rangeInvalidated;
    616630
    617631        LayoutUnit oldLogicalWidth = oldInfo->logicalWidth();
     
    665679}
    666680
    667 void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object,
    668     const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion,
    669     const RenderRegion* newStartRegion, const RenderRegion* newEndRegion)
     681void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object)
    670682{
    671683    // Clear the styles for the object in the regions.
    672     // The styles are not cleared for the regions that are contained in both ranges.
     684    // FIXME: Region styling is not computed only for the region range of the object so this is why we need to walk the whole chain.
     685    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
     686        RenderRegion* region = *iter;
     687        region->clearObjectStyleInRegion(object);
     688    }
     689}
     690
     691void RenderFlowThread::clearRenderBoxRegionInfoAndCustomStyle(const RenderBox* box,
     692    const RenderRegion* newStartRegion, const RenderRegion* newEndRegion,
     693    const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion)
     694{
     695    ASSERT(newStartRegion && newEndRegion && oldStartRegion && oldEndRegion);
     696
    673697    bool insideOldRegionRange = false;
    674698    bool insideNewRegionRange = false;
     
    681705            insideNewRegionRange = true;
    682706
    683         if (!(insideOldRegionRange && insideNewRegionRange))
    684             region->clearObjectStyleInRegion(object);
     707        if (!(insideOldRegionRange && insideNewRegionRange)) {
     708            region->clearObjectStyleInRegion(box);
     709            if (region->renderBoxRegionInfo(box))
     710                region->removeRenderBoxRegionInfo(box);
     711        }
    685712
    686713        if (oldEndRegion == region)
     
    691718}
    692719
    693 void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage)
    694 {
    695     if (!hasRegions())
    696         return;
    697 
    698     ASSERT(box->logicalHeight() >= 0);
    699 
    700     // FIXME: Not right for differing writing-modes.
    701     RenderRegion* startRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage, true);
    702     RenderRegion* endRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage + box->logicalHeight(), true);
     720void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, RenderRegion* startRegion, RenderRegion* endRegion)
     721{
     722    ASSERT(hasRegions());
     723    ASSERT(startRegion && endRegion);
     724
    703725    RenderRegionRangeMap::iterator it = m_regionRangeMap.find(box);
    704726    if (it == m_regionRangeMap.end()) {
    705727        m_regionRangeMap.set(box, RenderRegionRange(startRegion, endRegion));
    706         clearRenderObjectCustomStyle(box);
    707728        return;
    708729    }
     
    713734        return;
    714735
    715     // Delete any info that we find before our new startRegion and after our new endRegion.
    716     for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
    717         RenderRegion* region = *iter;
    718         if (region == startRegion) {
    719             iter = m_regionList.find(endRegion);
    720             continue;
    721         }
    722 
    723         region->removeRenderBoxRegionInfo(box);
    724 
    725         if (region == range.endRegion())
    726             break;
    727     }
    728 
    729     clearRenderObjectCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion);
     736    clearRenderBoxRegionInfoAndCustomStyle(box, startRegion, endRegion, range.startRegion(), range.endRegion());
    730737    range.setRange(startRegion, endRegion);
    731738}
     
    749756    // Simulate a region break at height. If it points inside an auto logical height region,
    750757    // then it may determine the region computed autoheight.
    751     addForcedRegionBreak(clientHeight, this, false);
     758    addForcedRegionBreak(this, clientHeight, this, false);
    752759}
    753760
     
    920927// it is possible that the break will occur at a different offset than the original one required.
    921928// offsetBreakAdjustment measures the different between the requested break offset and the current break offset.
    922 bool RenderFlowThread::addForcedRegionBreak(LayoutUnit offsetBreakInFlowThread, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment)
     929bool RenderFlowThread::addForcedRegionBreak(const RenderBlock* block, LayoutUnit offsetBreakInFlowThread, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment)
    923930{
    924931    // We take breaks into account for height computation for auto logical height regions
     
    947954    // Simulate a region break at offsetBreakInFlowThread. If it points inside an auto logical height region,
    948955    // then it determines the region computed auto height.
    949     RenderRegion* region = regionAtBlockOffset(offsetBreakInFlowThread);
     956    RenderRegion* region = regionAtBlockOffset(block, offsetBreakInFlowThread);
    950957    if (!region)
    951958        return false;
  • trunk/Source/WebCore/rendering/RenderFlowThread.h

    r153814 r153990  
    104104    LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary);
    105105
    106     virtual void setPageBreak(LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { }
    107     virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
     106    virtual void setPageBreak(const RenderBlock*, LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { }
     107    virtual void updateMinimumPageHeight(const RenderBlock*, LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
    108108
    109109    enum RegionAutoGenerationPolicy {
     
    111111        DisallowRegionAutoGeneration,
    112112    };
    113     RenderRegion* regionAtBlockOffset(LayoutUnit, bool extendLastRegion = false, RegionAutoGenerationPolicy = AllowRegionAutoGeneration);
     113
     114    RenderRegion* regionAtBlockOffset(const RenderBox*, LayoutUnit, bool extendLastRegion = false, RegionAutoGenerationPolicy = AllowRegionAutoGeneration);
    114115
    115116    bool regionsHaveUniformLogicalWidth() const { return m_regionsHaveUniformLogicalWidth; }
     
    131132    void updatePreviousRegionCount() { m_previousRegionCount = m_regionList.size(); };
    132133
    133     void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
     134    void setRegionRangeForBox(const RenderBox*, RenderRegion*, RenderRegion*);
    134135    void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
    135136
    136     void clearRenderObjectCustomStyle(const RenderObject*,
    137         const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
    138         const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
     137    void clearRenderObjectCustomStyle(const RenderObject*);
    139138
    140139    // Check if the object is in region and the region is part of this flow thread.
     
    144143    void markRegionsForOverflowLayoutIfNeeded();
    145144
    146     bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
     145    bool addForcedRegionBreak(const RenderBlock*, LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
    147146    void applyBreakAfterContent(LayoutUnit);
    148147
     
    179178    void popFlowThreadLayoutState();
    180179    LayoutUnit offsetFromLogicalTopOfFirstRegion(const RenderBlock*) const;
     180    void clearRenderBoxRegionInfoAndCustomStyle(const RenderBox*, const RenderRegion*, const RenderRegion*, const RenderRegion*, const RenderRegion*);
    181181
    182182    // Used to estimate the maximum height of the flow thread.
     
    238238            m_startRegion = start;
    239239            m_endRegion = end;
     240            m_rangeInvalidated = true;
    240241        }
    241242
    242243        RenderRegion* startRegion() const { return m_startRegion; }
    243244        RenderRegion* endRegion() const { return m_endRegion; }
     245        bool rangeInvalidated() const { return m_rangeInvalidated; }
     246        void clearRangeInvalidated() { m_rangeInvalidated = false; }
    244247
    245248    private:
    246249        RenderRegion* m_startRegion;
    247250        RenderRegion* m_endRegion;
     251        bool m_rangeInvalidated;
    248252    };
    249253
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r153748 r153990  
    154154    if (logicalWidthChangedInRegions(flowThread))
    155155        relayoutChildren = true;
    156     if (updateRegionsAndShapesBeforeChildLayout(flowThread))
     156    if (updateShapesBeforeBlockLayout())
    157157        relayoutChildren = true;
    158158
     
    172172    layoutPositionedObjects(relayoutChildren || isRoot());
    173173
    174     updateRegionsAndShapesAfterChildLayout(flowThread);
     174    updateShapesAfterBlockLayout();
    175175
    176176    computeOverflow(oldClientAfterEdge);
  • trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp

    r151545 r153990  
    105105}
    106106
    107 void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
     107void RenderMultiColumnFlowThread::setPageBreak(const RenderBlock* block, LayoutUnit offset, LayoutUnit spaceShortage)
    108108{
    109     if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
     109    if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(block, offset)))
    110110        multicolSet->recordSpaceShortage(spaceShortage);
    111111}
    112112
    113 void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
     113void RenderMultiColumnFlowThread::updateMinimumPageHeight(const RenderBlock* block, LayoutUnit offset, LayoutUnit minHeight)
    114114{
    115     if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
     115    if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(block, offset)))
    116116        multicolSet->updateMinimumColumnHeight(minHeight);
    117117}
  • trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h

    r153380 r153990  
    4545    virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) OVERRIDE;
    4646    virtual LayoutUnit initialLogicalWidth() const OVERRIDE;
    47     virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERRIDE;
    48     virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) OVERRIDE;
     47    virtual void setPageBreak(const RenderBlock*, LayoutUnit offset, LayoutUnit spaceShortage) OVERRIDE;
     48    virtual void updateMinimumPageHeight(const RenderBlock*, LayoutUnit offset, LayoutUnit minHeight) OVERRIDE;
    4949};
    5050
Note: See TracChangeset for help on using the changeset viewer.