Changeset 131348 in webkit


Ignore:
Timestamp:
Oct 15, 2012 1:31:47 PM (12 years ago)
Author:
mihnea@adobe.com
Message:

[CSSRegions]Add support for auto-height regions (without region-breaks)
https://bugs.webkit.org/show_bug.cgi?id=97533

Reviewed by Julien Chaffraix.

Source/WebCore:

Implement the 2pass layout algorithm for computing the height of regions with auto logical height, without taking region breaks into account.
The algorithm is described in the CSSRegions spec: http://dev.w3.org/csswg/css3-regions/#regions-visual-formatting-steps

When the flow thread contains regions with auto logical height, a 2pass layout algorithm is needed to determine the height of auto logical height regions.
In each step of the layout, the regions are laid out before the flow thread is laid out.

In the first pass of layout (normal layout phase), the content of the flow thread is laid out unconstrained in the regions. The region marked as having auto logical height
displays all the corresponding content from the flow thread (taking min-height and max-height into account), and the height of the content displayed
determines the overridden logical content height. Thus, after the first pass of layout, each auto logical height region will store the logical height
value for the second pass in its overridden logical content height property.

In the second pass of layout (constrained flow threads layout phase), when the content of the flow thread is laid out constrained in the regions, the regions are laid out again and they are using
the overridden logical content height from the first pass to update their logical height. Then, the flow thread content is laid out in the associated region chain,
for which the auto logical height regions have proper logical height.

A future patch will properly take region breaks into account for the first pass of layout.

Tests: fast/regions/autoheight-abspos-region.html

fast/regions/autoheight-floatright-region.html
fast/regions/autoheight-horizontal-bt.html
fast/regions/autoheight-inlineblock-normalflow-region.html
fast/regions/autoheight-maxheight-region.html
fast/regions/autoheight-minheight-region.html
fast/regions/autoheight-normalflow-region.html
fast/regions/autoheight-vertical-lr.html
fast/regions/autoheight-vertical-rl.html

  • rendering/FlowThreadController.cpp:

(WebCore::FlowThreadController::resetRegionsOverrideLogicalContentHeight):
For all the auto logical height regions, resets their associated overrideLogicalContentHeight.
Those regions are marked as needing layout (along with their ancestors).
(WebCore::FlowThreadController::markAutoLogicalHeightRegionsForLayout):
Mark all the auto logical height regions and their associated flow thread as needing layout (along with their ancestors).

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

Add helper functions to clear out individual logical content width/height.
(WebCore::RenderBox::clearOverrideLogicalContentHeight):
(WebCore::RenderBox::clearOverrideLogicalContentWidth):
(WebCore::RenderBox::clearOverrideSize):

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

(WebCore::RenderFlowThread::layout):
(WebCore::RenderFlowThread::computeLogicalHeight):
If the flow thread has an auto logical height region for which we did not yet compute the overrideLogicalContentHeight value,
bail out early since we cannot compute the flow thread logical height.
(WebCore::RenderFlowThread::regionAtBlockOffset):
If the offset is inside an auto logical height region for which we did not compute the overrideLogicalContentHeight, then we consider this region tall enough to accommodate all
the content and we return this region. Otherwise, for an auto logical height region, we use either the overrideLogicalContentHeight (if we are in the first layout phase) or
the logicalHeight if we are in the second layout phase (because the overriderLogicalContentHeight was already transferred into region logical height).
(WebCore::RenderFlowThread::pageLogicalHeightForOffset):
(WebCore::RenderFlowThread::pageRemainingLogicalHeightForOffset):
(WebCore::RenderFlowThread::computeOverflowStateForRegions):
(WebCore::RenderFlowThread::resetRegionsOverrideLogicalContentHeight):
(WebCore::RenderFlowThread::markAutoLogicalHeightRegionsForLayout):
(WebCore::RenderFlowThread::updateRegionsFlowThreadPortionRect):
(WebCore::RenderFlowThread::addForcedRegionBreak):
Simulate a region break at the specified offset. It will be extended to properly process the region breaks. At this moment, only one auto height region for a thread
can have its height properly computed.

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

(WebCore::boxIntersectsRegion):

  • rendering/RenderRegion.cpp:

(WebCore::RenderRegion::updateLogicalHeight):
If the auto logical height region has an overrideLogicalContentHeight and we are in the second pass of layout,
we use the overrideLogicalContentHeight to update the region logical height.
(WebCore::RenderRegion::needsOverrideLogicalContentHeightComputation):

  • rendering/RenderRegion.h:
  • rendering/RenderView.cpp:

(WebCore::RenderView::RenderView):
(WebCore::RenderView::layoutContent):
Added a new function to contain the RenderView block layout and flow threads layout.
(WebCore::RenderView::checkLayoutState):
Helper function keeping the original asserts from RenderView, used in more than one place.
(WebCore::RenderView::layout):

  • rendering/RenderView.h:

(WebCore::RenderView::normalLayoutPhase):
(WebCore::RenderView::constrainedFlowThreadsLayoutPhase):

LayoutTests:

Added tests for auto-height regions, with different writing modes, with min/max-height.
The bug referenced in the tests is the master bug for auto-height support, 91097.

  • fast/regions/autoheight-abspos-region-expected.html: Added.
  • fast/regions/autoheight-abspos-region.html: Added.
  • fast/regions/autoheight-floatright-region-expected.html: Added.
  • fast/regions/autoheight-floatright-region.html: Added.
  • fast/regions/autoheight-horizontal-bt-expected.html: Added.
  • fast/regions/autoheight-horizontal-bt.html: Added.
  • fast/regions/autoheight-inlineblock-normalflow-region-expected.html: Added.
  • fast/regions/autoheight-inlineblock-normalflow-region.html: Added.
  • fast/regions/autoheight-maxheight-region-expected.html: Added.
  • fast/regions/autoheight-maxheight-region.html: Added.
  • fast/regions/autoheight-minheight-region-expected.html: Added.
  • fast/regions/autoheight-minheight-region.html: Added.
  • fast/regions/autoheight-normalflow-region-expected.html: Added.
  • fast/regions/autoheight-normalflow-region.html: Added.
  • fast/regions/autoheight-vertical-lr-expected.html: Added.
  • fast/regions/autoheight-vertical-lr.html: Added.
  • fast/regions/autoheight-vertical-rl-expected.html: Added.
  • fast/regions/autoheight-vertical-rl.html: Added.
  • fast/regions/webkit-named-flow-first-empty-region-index.html: Fix an element style (though the test was passing before).
Location:
trunk
Files:
18 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r131346 r131348  
     12012-10-15  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSSRegions]Add support for auto-height regions (without region-breaks)
     4        https://bugs.webkit.org/show_bug.cgi?id=97533
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        Added tests for auto-height regions, with different writing modes, with min/max-height.
     9        The bug referenced in the tests is the master bug for auto-height support, 91097.
     10
     11        * fast/regions/autoheight-abspos-region-expected.html: Added.
     12        * fast/regions/autoheight-abspos-region.html: Added.
     13        * fast/regions/autoheight-floatright-region-expected.html: Added.
     14        * fast/regions/autoheight-floatright-region.html: Added.
     15        * fast/regions/autoheight-horizontal-bt-expected.html: Added.
     16        * fast/regions/autoheight-horizontal-bt.html: Added.
     17        * fast/regions/autoheight-inlineblock-normalflow-region-expected.html: Added.
     18        * fast/regions/autoheight-inlineblock-normalflow-region.html: Added.
     19        * fast/regions/autoheight-maxheight-region-expected.html: Added.
     20        * fast/regions/autoheight-maxheight-region.html: Added.
     21        * fast/regions/autoheight-minheight-region-expected.html: Added.
     22        * fast/regions/autoheight-minheight-region.html: Added.
     23        * fast/regions/autoheight-normalflow-region-expected.html: Added.
     24        * fast/regions/autoheight-normalflow-region.html: Added.
     25        * fast/regions/autoheight-vertical-lr-expected.html: Added.
     26        * fast/regions/autoheight-vertical-lr.html: Added.
     27        * fast/regions/autoheight-vertical-rl-expected.html: Added.
     28        * fast/regions/autoheight-vertical-rl.html: Added.
     29        * fast/regions/webkit-named-flow-first-empty-region-index.html: Fix an element style (though the test was passing before).
     30
    1312012-10-15  Dana Jansens  <danakj@chromium.org>
    232
  • trunk/LayoutTests/fast/regions/webkit-named-flow-first-empty-region-index.html

    r130041 r131348  
    99    .content { -webkit-flow-into: flow }
    1010    .region {  -webkit-flow-from: flow}
    11     #region, #region2, region3 {width: 250px; height: 50px}
     11    #region, #region2, #region3 { width: 250px; height: 50px; }
    1212</style>
    1313</head>
  • trunk/Source/WebCore/ChangeLog

    r131343 r131348  
     12012-10-15  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSSRegions]Add support for auto-height regions (without region-breaks)
     4        https://bugs.webkit.org/show_bug.cgi?id=97533
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        Implement the 2pass layout algorithm for computing the height of regions with auto logical height, without taking region breaks into account.
     9        The algorithm is described in the CSSRegions spec: http://dev.w3.org/csswg/css3-regions/#regions-visual-formatting-steps
     10
     11        When the flow thread contains regions with auto logical height, a 2pass layout algorithm is needed to determine the height of auto logical height regions.
     12        In each step of the layout, the regions are laid out before the flow thread is laid out.
     13
     14        In the first pass of layout (normal layout phase), the content of the flow thread is laid out unconstrained in the regions. The region marked as having auto logical height
     15        displays all the corresponding content from the flow thread (taking min-height and max-height into account), and the height of the content displayed
     16        determines the overridden logical content height. Thus, after the first pass of layout, each auto logical height region will store the logical height
     17        value for the second pass in its overridden logical content height property.
     18
     19        In the second pass of layout (constrained flow threads layout phase), when the content of the flow thread is laid out constrained in the regions, the regions are laid out again and they are using
     20        the overridden logical content height from the first pass to update their logical height. Then, the flow thread content is laid out in the associated region chain,
     21        for which the auto logical height regions have proper logical height.
     22
     23        A future patch will properly take region breaks into account for the first pass of layout.
     24
     25        Tests: fast/regions/autoheight-abspos-region.html
     26               fast/regions/autoheight-floatright-region.html
     27               fast/regions/autoheight-horizontal-bt.html
     28               fast/regions/autoheight-inlineblock-normalflow-region.html
     29               fast/regions/autoheight-maxheight-region.html
     30               fast/regions/autoheight-minheight-region.html
     31               fast/regions/autoheight-normalflow-region.html
     32               fast/regions/autoheight-vertical-lr.html
     33               fast/regions/autoheight-vertical-rl.html
     34
     35        * rendering/FlowThreadController.cpp:
     36        (WebCore::FlowThreadController::resetRegionsOverrideLogicalContentHeight):
     37        For all the auto logical height regions, resets their associated overrideLogicalContentHeight.
     38        Those regions are marked as needing layout (along with their ancestors).
     39        (WebCore::FlowThreadController::markAutoLogicalHeightRegionsForLayout):
     40        Mark all the auto logical height regions and their associated flow thread as needing layout (along with their ancestors).
     41        * rendering/FlowThreadController.h:
     42        * rendering/RenderBox.cpp:
     43        Add helper functions to clear out individual logical content width/height.
     44        (WebCore::RenderBox::clearOverrideLogicalContentHeight):
     45        (WebCore::RenderBox::clearOverrideLogicalContentWidth):
     46        (WebCore::RenderBox::clearOverrideSize):
     47        * rendering/RenderBox.h:
     48        * rendering/RenderFlowThread.cpp:
     49        (WebCore::RenderFlowThread::layout):
     50        (WebCore::RenderFlowThread::computeLogicalHeight):
     51        If the flow thread has an auto logical height region for which we did not yet compute the overrideLogicalContentHeight value,
     52        bail out early since we cannot compute the flow thread logical height.
     53        (WebCore::RenderFlowThread::regionAtBlockOffset):
     54        If the offset is inside an auto logical height region for which we did not compute the overrideLogicalContentHeight, then we consider this region tall enough to accommodate all
     55        the content and we return this region. Otherwise, for an auto logical height region, we use either the overrideLogicalContentHeight (if we are in the first layout phase) or
     56        the logicalHeight if we are in the second layout phase (because the overriderLogicalContentHeight was already transferred into region logical height).
     57        (WebCore::RenderFlowThread::pageLogicalHeightForOffset):
     58        (WebCore::RenderFlowThread::pageRemainingLogicalHeightForOffset):
     59        (WebCore::RenderFlowThread::computeOverflowStateForRegions):
     60        (WebCore::RenderFlowThread::resetRegionsOverrideLogicalContentHeight):
     61        (WebCore::RenderFlowThread::markAutoLogicalHeightRegionsForLayout):
     62        (WebCore::RenderFlowThread::updateRegionsFlowThreadPortionRect):
     63        (WebCore::RenderFlowThread::addForcedRegionBreak):
     64        Simulate a region break at the specified offset. It will be extended to properly process the region breaks. At this moment, only one auto height region for a thread
     65        can have its height properly computed.
     66        * rendering/RenderFlowThread.h:
     67        * rendering/RenderNamedFlowThread.cpp:
     68        (WebCore::boxIntersectsRegion):
     69        * rendering/RenderRegion.cpp:
     70        (WebCore::RenderRegion::updateLogicalHeight):
     71        If the auto logical height region has an overrideLogicalContentHeight and we are in the second pass of layout,
     72        we use the overrideLogicalContentHeight to update the region logical height.
     73        (WebCore::RenderRegion::needsOverrideLogicalContentHeightComputation):
     74        * rendering/RenderRegion.h:
     75        * rendering/RenderView.cpp:
     76        (WebCore::RenderView::RenderView):
     77        (WebCore::RenderView::layoutContent):
     78        Added a new function to contain the RenderView block layout and flow threads layout.
     79        (WebCore::RenderView::checkLayoutState):
     80        Helper function keeping the original asserts from RenderView, used in more than one place.
     81        (WebCore::RenderView::layout):
     82        * rendering/RenderView.h:
     83        (WebCore::RenderView::normalLayoutPhase):
     84        (WebCore::RenderView::constrainedFlowThreadsLayoutPhase):
     85
    1862012-10-15  Eugene Klyuchnikov  <eustas.bug@gmail.com>
    287
  • trunk/Source/WebCore/rendering/FlowThreadController.cpp

    r130612 r131348  
    177177#endif
    178178
     179void FlowThreadController::resetRegionsOverrideLogicalContentHeight()
     180{
     181    ASSERT(m_view->normalLayoutPhase());
     182    for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
     183        (*iter)->resetRegionsOverrideLogicalContentHeight();
     184}
     185
     186void FlowThreadController::markAutoLogicalHeightRegionsForLayout()
     187{
     188    ASSERT(m_view->constrainedFlowThreadsLayoutPhase());
     189    for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
     190        (*iter)->markAutoLogicalHeightRegionsForLayout();
     191}
     192
    179193} // namespace WebCore
  • trunk/Source/WebCore/rendering/FlowThreadController.h

    r128861 r131348  
    7676#endif
    7777
     78    void resetRegionsOverrideLogicalContentHeight();
     79    void markAutoLogicalHeightRegionsForLayout();
     80
    7881protected:
    7982    FlowThreadController(RenderView*);
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r131202 r131348  
    699699}
    700700
    701 void RenderBox::clearOverrideSize()
     701void RenderBox::clearOverrideLogicalContentHeight()
    702702{
    703703    if (gOverrideHeightMap)
    704704        gOverrideHeightMap->remove(this);
     705}
     706
     707void RenderBox::clearOverrideLogicalContentWidth()
     708{
    705709    if (gOverrideWidthMap)
    706710        gOverrideWidthMap->remove(this);
     711}
     712
     713void RenderBox::clearOverrideSize()
     714{
     715    clearOverrideLogicalContentHeight();
     716    clearOverrideLogicalContentWidth();
    707717}
    708718
  • trunk/Source/WebCore/rendering/RenderBox.h

    r131231 r131348  
    301301    void setOverrideLogicalContentWidth(LayoutUnit);
    302302    void clearOverrideSize();
     303    void clearOverrideLogicalContentHeight();
     304    void clearOverrideLogicalContentWidth();
    303305
    304306    virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r130918 r131348  
    165165           
    166166            updateLogicalWidth(); // Called to get the maximum logical width for the region.
    167            
    168             LayoutUnit logicalHeight = 0;
    169             for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
    170                 RenderRegion* region = *iter;
    171                    
    172                 LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
    173                 LayoutUnit regionLogicalHeight = region->logicalHeightOfAllFlowThreadContent();
    174    
    175                 LayoutRect regionRect(style()->direction() == LTR ? ZERO_LAYOUT_UNIT : logicalWidth() - regionLogicalWidth, logicalHeight, regionLogicalWidth, regionLogicalHeight);
    176                 region->setFlowThreadPortionRect(isHorizontalWritingMode() ? regionRect : regionRect.transposedRect());
    177                 logicalHeight += regionLogicalHeight;
    178             }
     167            updateRegionsFlowThreadPortionRect();
    179168        }
    180169    }
     
    221210        RenderRegion* region = *iter;
    222211        ASSERT(!region->needsLayout());
     212
     213        if (region->needsOverrideLogicalContentHeightComputation()) {
     214            // If we have an auto logical height region for which we did not compute a height yet,
     215            // then we cannot compute and update the height of this flow.
     216            return;
     217        }
     218
    223219        computedValues.m_extent += region->logicalHeightOfAllFlowThreadContent();
    224220    }
     
    325321    // the last valid region. It is similar to auto extending the size of the last region.
    326322    RenderRegion* lastValidRegion = 0;
     323
     324    LayoutUnit accumulatedLogicalHeight = ZERO_LAYOUT_UNIT;
    327325   
    328326    // FIXME: The regions are always in order, optimize this search.
    329     bool useHorizontalWritingMode = isHorizontalWritingMode();
    330327    for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
    331328        RenderRegion* region = *iter;
     
    334331            return region;
    335332
    336         LayoutRect regionRect = region->flowThreadPortionRect();
    337         if ((useHorizontalWritingMode && offset < regionRect.maxY()) || (!useHorizontalWritingMode && offset < regionRect.maxX()))
    338             return region;
    339 
    340333        if (extendLastRegion || region->isRenderRegionSet())
    341334            lastValidRegion = region;
     335
     336        // If we did not compute the region's height, we should consider this region
     337        // tall enough to accomodate all content.
     338        if (region->needsOverrideLogicalContentHeightComputation())
     339            return region;
     340
     341        if (region->hasOverrideHeight() && view()->normalLayoutPhase()) {
     342            accumulatedLogicalHeight += region->overrideLogicalContentHeight();
     343            if (offset < accumulatedLogicalHeight)
     344                return region;
     345            continue;
     346        }
     347
     348        LayoutRect regionRect = region->flowThreadPortionRect();
     349        accumulatedLogicalHeight += isHorizontalWritingMode() ? regionRect.height() : regionRect.width();
     350        if (offset < accumulatedLogicalHeight)
     351            return region;
    342352    }
    343353
     
    358368
    359369LayoutUnit RenderFlowThread::pageLogicalHeightForOffset(LayoutUnit offset) const
    360 {
    361     RenderRegion* region = regionAtBlockOffset(offset);
    362     return region ? region->pageLogicalHeight() : ZERO_LAYOUT_UNIT;
    363 }
    364 
    365 LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
    366370{
    367371    RenderRegion* region = regionAtBlockOffset(offset);
    368372    if (!region)
    369373        return ZERO_LAYOUT_UNIT;
    370    
     374    if (region->needsOverrideLogicalContentHeightComputation())
     375        return MAX_LAYOUT_UNIT / 2;
     376    return region->pageLogicalHeight();
     377}
     378
     379LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
     380{
     381    RenderRegion* region = regionAtBlockOffset(offset);
     382    if (!region)
     383        return ZERO_LAYOUT_UNIT;
     384    if (region->needsOverrideLogicalContentHeightComputation())
     385        return MAX_LAYOUT_UNIT / 2;
     386
    371387    LayoutUnit pageLogicalTop = region->pageLogicalTopForOffset(offset);
    372388    LayoutUnit pageLogicalHeight = region->pageLogicalHeight();
     
    581597{
    582598    LayoutUnit height = oldClientAfterEdge;
     599
     600    // Simulate a region break at height. If it points inside an auto logical height region,
     601    // then it determines the region override logical content height.
     602    addForcedRegionBreak(height);
     603
    583604    // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
    584605    // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
     
    705726#endif
    706727
     728void RenderFlowThread::resetRegionsOverrideLogicalContentHeight()
     729{
     730    ASSERT(view()->layoutState());
     731    ASSERT(view()->normalLayoutPhase());
     732
     733    // We need to reset the override logical content height for regions with auto logical height
     734    // only if the flow thread content needs layout.
     735    if (!selfNeedsLayout())
     736        return;
     737
     738    // FIXME: optimize this to iterate the region chain only if the flow thread has auto logical height
     739    // region.
     740
     741    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
     742        RenderRegion* region = *iter;
     743        if (!region->hasAutoLogicalHeight())
     744            continue;
     745
     746        region->clearOverrideLogicalContentHeight();
     747        // FIXME: We need to find a way to avoid marking all the regions ancestors for layout
     748        // as we are already inside layout.
     749        region->setNeedsLayout(true);
     750    }
     751}
     752
     753void RenderFlowThread::markAutoLogicalHeightRegionsForLayout()
     754{
     755    ASSERT(view()->layoutState());
     756    ASSERT(view()->constrainedFlowThreadsLayoutPhase());
     757
     758    // FIXME: optimize this to iterate the region chain only if the flow thread has auto logical height
     759    // region.
     760
     761    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
     762        RenderRegion* region = *iter;
     763        if (!region->hasAutoLogicalHeight())
     764            continue;
     765
     766        // FIXME: We need to find a way to avoid marking all the regions ancestors for layout
     767        // as we are already inside layout.
     768        region->setNeedsLayout(true);
     769    }
     770
     771    m_regionsInvalidated = true;
     772    setNeedsLayout(true);
     773}
     774
     775void RenderFlowThread::updateRegionsFlowThreadPortionRect()
     776{
     777    LayoutUnit logicalHeight = 0;
     778    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
     779        RenderRegion* region = *iter;
     780
     781        LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
     782        LayoutUnit regionLogicalHeight = region->logicalHeightOfAllFlowThreadContent();
     783
     784        LayoutRect regionRect(style()->direction() == LTR ? ZERO_LAYOUT_UNIT : logicalWidth() - regionLogicalWidth, logicalHeight, regionLogicalWidth, regionLogicalHeight);
     785
     786        // FIXME: when a flow thread has more than one auto logical height region,
     787        // we have to take into account the override logical content height value,
     788        // if computed for an auto logical height region, and use it to set the height
     789        // for the region rect. This way, the regions in the chain following the auto
     790        // logical height region, will be able to fragment the right part of their
     791        // associated flow thread content (and compute their overrideComputedLogicalHeight properly).
     792
     793        region->setFlowThreadPortionRect(isHorizontalWritingMode() ? regionRect : regionRect.transposedRect());
     794        logicalHeight += regionLogicalHeight;
     795    }
     796}
     797
     798// FIXME: Extend it to account for region break
     799void RenderFlowThread::addForcedRegionBreak(LayoutUnit offsetBreakInFlowThread)
     800{
     801    // We take breaks into account for height computation for auto logical height regions
     802    // only in the layout phase in which we lay out the flows threads unconstrained
     803    // and we use the content breaks to determine the overrideContentLogicalHeight for
     804    // auto logical height regions.
     805    if (view()->constrainedFlowThreadsLayoutPhase())
     806        return;
     807
     808    // Simulate a region break at height. If it points inside an auto logical height region,
     809    // then it determines the region override logical content height.
     810    RenderRegion* region = regionAtBlockOffset(offsetBreakInFlowThread);
     811    if (!region)
     812        return;
     813
     814    if (!region->needsOverrideLogicalContentHeightComputation())
     815        return;
     816
     817    LayoutUnit currentRegionOffsetInFlowThread = isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x();
     818    LayoutUnit offsetBreakInCurrentRegion = offsetBreakInFlowThread - currentRegionOffsetInFlowThread;
     819    LayoutUnit regionOverrideLogicalContentHeight = region->computeReplacedLogicalHeightRespectingMinMaxHeight(offsetBreakInCurrentRegion);
     820    region->setOverrideLogicalContentHeight(regionOverrideLogicalContentHeight);
     821
     822    // FIXME: Extend it to take into account that we may have more than one auto-height region in flow.
     823    // For now, clear the override logical content height for remaining auto logical height regions in the flow.
     824    // A follow-up patch will properly distribute the remaining height into the following regions.
     825    RenderRegionList::iterator regionIter = m_regionList.find(region);
     826    ASSERT(regionIter != m_regionList.end());
     827
     828    // Skip the current region.
     829    ++regionIter;
     830
     831    for (; regionIter != m_regionList.end(); ++regionIter) {
     832        RenderRegion* currRegion = *regionIter;
     833        if (!currRegion->hasAutoLogicalHeight())
     834            continue;
     835        currRegion->clearOverrideLogicalContentHeight();
     836    }
     837
     838    updateRegionsFlowThreadPortionRect();
     839}
     840
    707841CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowThread* renderFlowThread)
    708842    : m_renderFlowThread(renderFlowThread)
  • trunk/Source/WebCore/rendering/RenderFlowThread.h

    r130918 r131348  
    119119
    120120    void clearRenderObjectCustomStyle(const RenderObject*,
    121                                       const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
    122                                       const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
     121        const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
     122        const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
    123123   
    124124    void computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge);
     
    128128    // Check if the object is in region and the region is part of this flow thread.
    129129    bool objectInFlowRegion(const RenderObject*, const RenderRegion*) const;
     130
     131    void resetRegionsOverrideLogicalContentHeight();
     132    void markAutoLogicalHeightRegionsForLayout();
     133
     134    void addForcedRegionBreak(LayoutUnit);
    130135
    131136    bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
     
    138143    virtual const char* renderName() const = 0;
    139144
     145    void updateRegionsFlowThreadPortionRect();
    140146    bool shouldRepaint(const LayoutRect&) const;
    141147    bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
  • trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp

    r130918 r131348  
    436436{
    437437    bool regionIsEmpty = logicalBottomForRegion != MAX_LAYOUT_UNIT && logicalTopForRegion != MIN_LAYOUT_UNIT
    438                          && (logicalBottomForRegion - logicalTopForRegion) <= 0;
     438        && (logicalBottomForRegion - logicalTopForRegion) <= 0;
    439439    return  (logicalBottomForBox - logicalTopForBox) > 0
    440             && !regionIsEmpty
    441             && logicalTopForBox < logicalBottomForRegion && logicalTopForRegion < logicalBottomForBox;
     440        && !regionIsEmpty
     441        && logicalTopForBox < logicalBottomForRegion && logicalTopForRegion < logicalBottomForBox;
    442442}
    443443
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r130612 r131348  
    473473    return renderObjectRegionStyle.release();
    474474}
    475  
     475
    476476void RenderRegion::computeChildrenStyleInRegion(const RenderObject* object)
    477477{
     
    499499    }
    500500}
    501  
     501
    502502void RenderRegion::setObjectStyleInRegion(RenderObject* object, PassRefPtr<RenderStyle> styleInRegion, bool objectRegionStyleCached)
    503503{
     
    523523    m_renderObjectRegionStyle.set(object, styleInfo);
    524524}
    525  
     525
    526526void RenderRegion::clearObjectStyleInRegion(const RenderObject* object)
    527527{
     
    580580}
    581581
     582void RenderRegion::updateLogicalHeight()
     583{
     584    RenderReplaced::updateLogicalHeight();
     585
     586    if (!hasAutoLogicalHeight())
     587        return;
     588
     589    // We want to update the logical height based on the computed override logical
     590    // content height only if the view is in the layout phase
     591    // in which all the auto logical height regions have their override logical height set.
     592    if (view()->normalLayoutPhase())
     593        return;
     594
     595    // There may be regions with auto logical height that during the prerequisite layout phase
     596    // did not have the chance to layout flow thread content. Because of that, these regions do not
     597    // have an overrideLogicalContentHeight computed and they will not be able to fragment any flow
     598    // thread content.
     599    if (!hasOverrideHeight())
     600        return;
     601
     602    LayoutUnit newLogicalHeight = overrideLogicalContentHeight() + borderAndPaddingLogicalHeight();
     603    if (newLogicalHeight > logicalHeight())
     604        setLogicalHeight(newLogicalHeight);
     605}
     606
     607bool RenderRegion::needsOverrideLogicalContentHeightComputation() const
     608{
     609    return hasAutoLogicalHeight() && view()->normalLayoutPhase() && !hasOverrideHeight();
     610}
     611
    582612} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r128861 r131348  
    123123    bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; }
    124124
     125    bool needsOverrideLogicalContentHeightComputation() const;
     126
     127    virtual void updateLogicalHeight() OVERRIDE;
     128
    125129    // The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the
    126130    // flow thread portion we contain. For sets, we have to figure out the top of the nearest column or
     
    141145    LayoutRect overflowRectForFlowThreadPortion(LayoutRect flowThreadPortionRect, bool isFirstPortion, bool isLastPortion) const;
    142146    void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect,
    143                                            const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
     147        const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
    144148
    145149private:
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r131111 r131348  
    6666    , m_renderQuoteHead(0)
    6767    , m_renderCounterCount(0)
     68    , m_layoutPhase(RenderViewNormalLayout)
    6869{
    6970    // Clear our anonymous bit, set because RenderObject assumes
     
    132133    return child->isBox();
    133134}
     135
     136void RenderView::layoutContent(const LayoutState& state)
     137{
     138    ASSERT(needsLayout());
     139
     140    RenderBlock::layout();
     141    if (hasRenderNamedFlowThreads())
     142        flowThreadController()->layoutRenderNamedFlowThreads();
     143#ifndef NDEBUG
     144    checkLayoutState(state);
     145#endif
     146}
     147
     148#ifndef NDEBUG
     149void RenderView::checkLayoutState(const LayoutState& state)
     150{
     151    ASSERT(layoutDelta() == LayoutSize());
     152    ASSERT(!m_layoutStateDisableCount);
     153    ASSERT(m_layoutState == &state);
     154}
     155#endif
    134156
    135157void RenderView::layout()
     
    155177
    156178    ASSERT(!m_layoutState);
     179    if (!needsLayout())
     180        return;
     181
    157182    LayoutState state;
    158183    // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
     
    164189    m_layoutState = &state;
    165190
    166     if (needsLayout()) {
    167         RenderBlock::layout();
    168         if (hasRenderNamedFlowThreads())
    169             flowThreadController()->layoutRenderNamedFlowThreads();
    170     }
    171 
    172     ASSERT(layoutDelta() == LayoutSize());
    173     ASSERT(m_layoutStateDisableCount == 0);
    174     ASSERT(m_layoutState == &state);
     191    m_layoutPhase = RenderViewNormalLayout;
     192    bool needsTwoPassLayoutForAutoLogicalHeightRegions = hasRenderNamedFlowThreads() && flowThreadController()->hasAutoLogicalHeightRegions();
     193
     194    if (needsTwoPassLayoutForAutoLogicalHeightRegions)
     195        flowThreadController()->resetRegionsOverrideLogicalContentHeight();
     196
     197    layoutContent(state);
     198
     199    if (needsTwoPassLayoutForAutoLogicalHeightRegions) {
     200        m_layoutPhase = ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions;
     201        flowThreadController()->markAutoLogicalHeightRegionsForLayout();
     202        layoutContent(state);
     203    }
     204
     205#ifndef NDEBUG
     206    checkLayoutState(state);
     207#endif
    175208    m_layoutState = 0;
    176209    setNeedsLayout(false);
  • trunk/Source/WebCore/rendering/RenderView.h

    r131231 r131348  
    189189    FlowThreadController* flowThreadController();
    190190
     191    enum RenderViewLayoutPhase { RenderViewNormalLayout, ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions };
     192    bool normalLayoutPhase() const { return m_layoutPhase == RenderViewNormalLayout; }
     193    bool constrainedFlowThreadsLayoutPhase() const { return m_layoutPhase == ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions; }
     194
    191195    void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    192196
     
    249253    void disableLayoutState() { m_layoutStateDisableCount++; }
    250254    void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
     255
     256    void layoutContent(const LayoutState&);
     257#ifndef NDEBUG
     258    void checkLayoutState(const LayoutState&);
     259#endif
    251260
    252261    size_t getRetainedWidgets(Vector<RenderWidget*>&);
     
    308317    RenderQuote* m_renderQuoteHead;
    309318    unsigned m_renderCounterCount;
     319    RenderViewLayoutPhase m_layoutPhase;
    310320};
    311321
Note: See TracChangeset for help on using the changeset viewer.