Changeset 140400 in webkit


Ignore:
Timestamp:
Jan 22, 2013 1:43:45 AM (11 years ago)
Author:
mihnea@adobe.com
Message:

[CSS Regions] min-max height will not trigger a relayout when set on a region with auto-height
https://bugs.webkit.org/show_bug.cgi?id=103738

Reviewed by David Hyatt.

Source/WebCore:

When the style of an auto-height region changes with different min/max-height, we have to make sure
that the 2-pass layout algorithm is run so that the region height is properly computed. When doing a 2-pass layout
for auto-height regions, we have to make sure that in the first pass, all auto-height regions start without a previously
computed overrideLogicalContentHeight, otherwise we may end-up with incorrect results, illustrated by tests
autoheight-two-pass-layout-complex-001.html and autoheight-two-pass-layout-complex-002.html.

If we do not have auto height regions, a single pass layout in enough to correctly flow content inside regions.
When we have auto height regions, the algorithm to lay out content should be:

  1. If the flow thread content does not need lay out, we do a single pass layout.

If during the layout, an auto-height region needs layout or a normal (not auto height) region changes its box dimensions,
we need to perform a new 2-pass layout after this layout completes. If not, we bail out and skip step 2.

  1. Do a full two pass layout and make sure that all auto height regions start the 2-pass layout without a previously computed

override logical content height.

Tests: fast/regions/autoheight-region-decrease-maxheight.html

fast/regions/autoheight-region-decrease-minheight.html
fast/regions/autoheight-region-decrease-width.html
fast/regions/autoheight-region-increase-maxheight.html
fast/regions/autoheight-region-increase-minheight.html
fast/regions/autoheight-region-increase-width.html
fast/regions/autoheight-region-new-maxheight-vrl.html
fast/regions/autoheight-region-new-maxheight.html
fast/regions/autoheight-region-new-minheight-vlr.html
fast/regions/autoheight-region-new-minheight.html
fast/regions/autoheight-region-remove-maxheight.html
fast/regions/autoheight-region-remove-minheight.html
fast/regions/autoheight-two-pass-layout-complex-001.html
fast/regions/autoheight-two-pass-layout-complex-002.html
fast/regions/region-height-auto-to-defined.html
fast/regions/region-height-defined-to-auto.html

  • rendering/FlowThreadController.cpp: Added a flag that is needed to mark whether we need a full 2-pass layout.

(WebCore::FlowThreadController::FlowThreadController):

  • rendering/FlowThreadController.h:

(WebCore::FlowThreadController::needsTwoPassLayoutForAutoHeightRegions):
(WebCore::FlowThreadController::setNeedsTwoPassLayoutForAutoHeightRegions):

  • rendering/RenderFlowThread.cpp:

(WebCore::RenderFlowThread::resetRegionsOverrideLogicalContentHeight): Use invalidateRegions because we need also to mark the flow thread as needing layout.
(WebCore::RenderFlowThread::markAutoLogicalHeightRegionsForLayout):

  • rendering/RenderRegion.cpp:

(WebCore::RenderRegion::layout): Make sure we do a 2-pass layout if needed.

  • rendering/RenderView.cpp:

(WebCore::RenderView::layoutContentInAutoLogicalHeightRegions): Added a new function that models the layout algorithm for the case when we have auto height regions
and flow threads.
(WebCore::RenderView::layout):
(WebCore::RenderView::checkTwoPassLayoutForAutoHeightRegions):

  • rendering/RenderView.h:

LayoutTests:

Added tests for dynamically change the min/max-height for auto-height regions, including also vertical writing modes.
Added tests for dynamically changing the width of auto-height regions to make sure we are correctly computing their height.
Added two tests for complex auto-height regions layout which require a full two-pass layout after some regions from region
chain are laid out.

  • fast/regions/autoheight-region-decrease-maxheight-expected.txt: Added.
  • fast/regions/autoheight-region-decrease-maxheight.html: Added.
  • fast/regions/autoheight-region-decrease-minheight-expected.txt: Added.
  • fast/regions/autoheight-region-decrease-minheight.html: Added.
  • fast/regions/autoheight-region-decrease-width-expected.txt: Added.
  • fast/regions/autoheight-region-decrease-width.html: Added.
  • fast/regions/autoheight-region-increase-maxheight-expected.txt: Added.
  • fast/regions/autoheight-region-increase-maxheight.html: Added.
  • fast/regions/autoheight-region-increase-minheight-expected.txt: Added.
  • fast/regions/autoheight-region-increase-minheight.html: Added.
  • fast/regions/autoheight-region-increase-width-expected.txt: Added.
  • fast/regions/autoheight-region-increase-width.html: Added.
  • fast/regions/autoheight-region-new-maxheight-expected.txt: Added.
  • fast/regions/autoheight-region-new-maxheight-vrl-expected.txt: Added.
  • fast/regions/autoheight-region-new-maxheight-vrl.html: Added.
  • fast/regions/autoheight-region-new-maxheight.html: Added.
  • fast/regions/autoheight-region-new-minheight-expected.txt: Added.
  • fast/regions/autoheight-region-new-minheight-vlr-expected.txt: Added.
  • fast/regions/autoheight-region-new-minheight-vlr.html: Added.
  • fast/regions/autoheight-region-new-minheight.html: Added.
  • fast/regions/autoheight-region-remove-maxheight-expected.txt: Added.
  • fast/regions/autoheight-region-remove-maxheight.html: Added.
  • fast/regions/autoheight-region-remove-minheight-expected.txt: Added.
  • fast/regions/autoheight-region-remove-minheight.html: Added.
  • fast/regions/autoheight-two-pass-layout-complex-001-expected.txt: Added.
  • fast/regions/autoheight-two-pass-layout-complex-001.html: Added.
  • fast/regions/autoheight-two-pass-layout-complex-002-expected.txt: Added.
  • fast/regions/autoheight-two-pass-layout-complex-002.html: Added.
  • fast/regions/region-height-auto-to-defined-expected.txt: Added.
  • fast/regions/region-height-auto-to-defined.html: Added.
  • fast/regions/region-height-defined-to-auto-expected.txt: Added.
  • fast/regions/region-height-defined-to-auto.html: Added.
Location:
trunk
Files:
32 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r140398 r140400  
     12013-01-22  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSS Regions] min-max height will not trigger a relayout when set on a region with auto-height
     4        https://bugs.webkit.org/show_bug.cgi?id=103738
     5
     6        Reviewed by David Hyatt.
     7
     8        Added tests for dynamically change the min/max-height for auto-height regions, including also vertical writing modes.
     9        Added tests for dynamically changing the width of auto-height regions to make sure we are correctly computing their height.
     10        Added two tests for complex auto-height regions layout which require a full two-pass layout after some regions from region
     11        chain are laid out.
     12
     13        * fast/regions/autoheight-region-decrease-maxheight-expected.txt: Added.
     14        * fast/regions/autoheight-region-decrease-maxheight.html: Added.
     15        * fast/regions/autoheight-region-decrease-minheight-expected.txt: Added.
     16        * fast/regions/autoheight-region-decrease-minheight.html: Added.
     17        * fast/regions/autoheight-region-decrease-width-expected.txt: Added.
     18        * fast/regions/autoheight-region-decrease-width.html: Added.
     19        * fast/regions/autoheight-region-increase-maxheight-expected.txt: Added.
     20        * fast/regions/autoheight-region-increase-maxheight.html: Added.
     21        * fast/regions/autoheight-region-increase-minheight-expected.txt: Added.
     22        * fast/regions/autoheight-region-increase-minheight.html: Added.
     23        * fast/regions/autoheight-region-increase-width-expected.txt: Added.
     24        * fast/regions/autoheight-region-increase-width.html: Added.
     25        * fast/regions/autoheight-region-new-maxheight-expected.txt: Added.
     26        * fast/regions/autoheight-region-new-maxheight-vrl-expected.txt: Added.
     27        * fast/regions/autoheight-region-new-maxheight-vrl.html: Added.
     28        * fast/regions/autoheight-region-new-maxheight.html: Added.
     29        * fast/regions/autoheight-region-new-minheight-expected.txt: Added.
     30        * fast/regions/autoheight-region-new-minheight-vlr-expected.txt: Added.
     31        * fast/regions/autoheight-region-new-minheight-vlr.html: Added.
     32        * fast/regions/autoheight-region-new-minheight.html: Added.
     33        * fast/regions/autoheight-region-remove-maxheight-expected.txt: Added.
     34        * fast/regions/autoheight-region-remove-maxheight.html: Added.
     35        * fast/regions/autoheight-region-remove-minheight-expected.txt: Added.
     36        * fast/regions/autoheight-region-remove-minheight.html: Added.
     37        * fast/regions/autoheight-two-pass-layout-complex-001-expected.txt: Added.
     38        * fast/regions/autoheight-two-pass-layout-complex-001.html: Added.
     39        * fast/regions/autoheight-two-pass-layout-complex-002-expected.txt: Added.
     40        * fast/regions/autoheight-two-pass-layout-complex-002.html: Added.
     41        * fast/regions/region-height-auto-to-defined-expected.txt: Added.
     42        * fast/regions/region-height-auto-to-defined.html: Added.
     43        * fast/regions/region-height-defined-to-auto-expected.txt: Added.
     44        * fast/regions/region-height-defined-to-auto.html: Added.
     45
    1462013-01-22  Manuel Rego Casasnovas  <rego@igalia.com>
    247
  • trunk/Source/WebCore/ChangeLog

    r140399 r140400  
     12013-01-22  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSS Regions] min-max height will not trigger a relayout when set on a region with auto-height
     4        https://bugs.webkit.org/show_bug.cgi?id=103738
     5
     6        Reviewed by David Hyatt.
     7
     8        When the style of an auto-height region changes with different min/max-height, we have to make sure
     9        that the 2-pass layout algorithm is run so that the region height is properly computed. When doing a 2-pass layout
     10        for auto-height regions, we have to make sure that in the first pass, all auto-height regions start without a previously
     11        computed overrideLogicalContentHeight, otherwise we may end-up with incorrect results, illustrated by tests
     12        autoheight-two-pass-layout-complex-001.html and autoheight-two-pass-layout-complex-002.html.
     13
     14        If we do not have auto height regions, a single pass layout in enough to correctly flow content inside regions.
     15        When we have auto height regions, the algorithm to lay out content should be:
     16        1. If the flow thread content does not need lay out, we do a single pass layout.
     17        If during the layout, an auto-height region needs layout or a normal (not auto height) region changes its box dimensions,
     18        we need to perform a new 2-pass layout after this layout completes. If not, we bail out and skip step 2.
     19        2. Do a full two pass layout and make sure that all auto height regions start the 2-pass layout without a previously computed
     20        override logical content height.
     21
     22        Tests: fast/regions/autoheight-region-decrease-maxheight.html
     23               fast/regions/autoheight-region-decrease-minheight.html
     24               fast/regions/autoheight-region-decrease-width.html
     25               fast/regions/autoheight-region-increase-maxheight.html
     26               fast/regions/autoheight-region-increase-minheight.html
     27               fast/regions/autoheight-region-increase-width.html
     28               fast/regions/autoheight-region-new-maxheight-vrl.html
     29               fast/regions/autoheight-region-new-maxheight.html
     30               fast/regions/autoheight-region-new-minheight-vlr.html
     31               fast/regions/autoheight-region-new-minheight.html
     32               fast/regions/autoheight-region-remove-maxheight.html
     33               fast/regions/autoheight-region-remove-minheight.html
     34               fast/regions/autoheight-two-pass-layout-complex-001.html
     35               fast/regions/autoheight-two-pass-layout-complex-002.html
     36               fast/regions/region-height-auto-to-defined.html
     37               fast/regions/region-height-defined-to-auto.html
     38
     39        * rendering/FlowThreadController.cpp: Added a flag that is needed to mark whether we need a full 2-pass layout.
     40        (WebCore::FlowThreadController::FlowThreadController):
     41        * rendering/FlowThreadController.h:
     42        (WebCore::FlowThreadController::needsTwoPassLayoutForAutoHeightRegions):
     43        (WebCore::FlowThreadController::setNeedsTwoPassLayoutForAutoHeightRegions):
     44        * rendering/RenderFlowThread.cpp:
     45        (WebCore::RenderFlowThread::resetRegionsOverrideLogicalContentHeight): Use invalidateRegions because we need also to mark the flow thread as needing layout.
     46        (WebCore::RenderFlowThread::markAutoLogicalHeightRegionsForLayout):
     47        * rendering/RenderRegion.cpp:
     48        (WebCore::RenderRegion::layout): Make sure we do a 2-pass layout if needed.
     49        * rendering/RenderView.cpp:
     50        (WebCore::RenderView::layoutContentInAutoLogicalHeightRegions): Added a new function that models the layout algorithm for the case when we have auto height regions
     51        and flow threads.
     52        (WebCore::RenderView::layout):
     53        (WebCore::RenderView::checkTwoPassLayoutForAutoHeightRegions):
     54        * rendering/RenderView.h:
     55
    1562013-01-22  Adam Barth  <abarth@webkit.org>
    257
  • trunk/Source/WebCore/rendering/FlowThreadController.cpp

    r136346 r140400  
    5050    , m_currentRenderFlowThread(0)
    5151    , m_isRenderNamedFlowThreadOrderDirty(false)
     52    , m_needsTwoPassLayoutForAutoHeightRegions(false)
    5253    , m_autoLogicalHeightRegionsCount(0)
    5354{
  • trunk/Source/WebCore/rendering/FlowThreadController.h

    r136346 r140400  
    8181    void markAutoLogicalHeightRegionsForLayout();
    8282
     83    bool needsTwoPassLayoutForAutoHeightRegions() const { return m_needsTwoPassLayoutForAutoHeightRegions; }
     84    void setNeedsTwoPassLayoutForAutoHeightRegions(bool needsTwoPassLayout) { m_needsTwoPassLayoutForAutoHeightRegions = needsTwoPassLayout; }
     85
    8386protected:
    8487    FlowThreadController(RenderView*);
     
    8891    RenderFlowThread* m_currentRenderFlowThread;
    8992    bool m_isRenderNamedFlowThreadOrderDirty;
     93    bool m_needsTwoPassLayoutForAutoHeightRegions;
    9094    unsigned m_autoLogicalHeightRegionsCount;
    9195    OwnPtr<RenderNamedFlowThreadList> m_renderNamedFlowThreadList;
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r140244 r140400  
    759759    ASSERT(view()->normalLayoutPhase());
    760760
    761     // We need to reset the override logical content height for regions with auto logical height
    762     // only if the flow thread content needs layout.
    763     if (!needsLayout())
    764         return;
    765 
    766761    // FIXME: optimize this to iterate the region chain only if the flow thread has auto logical height
    767762    // region.
     
    779774    // Make sure we don't skip any region breaks when we do the layout again.
    780775    // Using m_regionsInvalidated to force all the RenderFlowThread children do the layout again.
    781     m_regionsInvalidated = true;
     776    invalidateRegions();
    782777}
    783778
     
    814809    }
    815810
    816     m_regionsInvalidated = true;
    817     setNeedsLayout(true);
     811    invalidateRegions();
    818812}
    819813
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r140244 r140400  
    229229        if (!isHorizontalWritingMode())
    230230            oldRegionRect = oldRegionRect.transposedRect();
    231         if (oldRegionRect.width() != pageLogicalWidth() || oldRegionRect.height() != pageLogicalHeight())
     231
     232        if (view()->checkTwoPassLayoutForAutoHeightRegions() && hasAutoLogicalHeight())
     233            view()->flowThreadController()->setNeedsTwoPassLayoutForAutoHeightRegions(true);
     234
     235        if (oldRegionRect.width() != pageLogicalWidth() || oldRegionRect.height() != pageLogicalHeight()) {
    232236            m_flowThread->invalidateRegions();
     237            if (view()->checkTwoPassLayoutForAutoHeightRegions())
     238                view()->flowThreadController()->setNeedsTwoPassLayoutForAutoHeightRegions(true);
     239        }
    233240    }
    234241
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r140244 r140400  
    146146#endif
    147147
     148// The algorithm to layout the flow thread content in auto height regions has to make sure
     149// that when a two-pass layout is needed, the auto height regions always start the first
     150// pass without a computed override logical content height (from previous layouts).
     151// This way, the layout algorithm gives the same result in all situations.
     152// If the flow thread content does not need layout, the decision of whether we need a full
     153// two pass layout cannot be made up-front. Therefore, we do a first layout, and if an auto
     154// height region needs layout or a non-auto height region changes its box dimensions,
     155// we need to perform a full two pass layout.
     156void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state)
     157{
     158    ASSERT(!flowThreadController()->needsTwoPassLayoutForAutoHeightRegions());
     159
     160    if (!flowThreadController()->hasRenderNamedFlowThreadsNeedingLayout()) {
     161        layoutContent(state);
     162        if (!flowThreadController()->needsTwoPassLayoutForAutoHeightRegions())
     163            return;
     164    }
     165
     166    // Start a full two phase layout for regions with auto logical height.
     167    flowThreadController()->resetRegionsOverrideLogicalContentHeight();
     168    layoutContent(state);
     169
     170    m_layoutPhase = ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions;
     171    flowThreadController()->markAutoLogicalHeightRegionsForLayout();
     172    layoutContent(state);
     173    flowThreadController()->setNeedsTwoPassLayoutForAutoHeightRegions(false);
     174}
     175
    148176void RenderView::layout()
    149177{
     
    182210
    183211    m_layoutPhase = RenderViewNormalLayout;
    184     bool needsTwoPassLayoutForAutoLogicalHeightRegions = hasRenderNamedFlowThreads()
    185         && flowThreadController()->hasAutoLogicalHeightRegions()
    186         && flowThreadController()->hasRenderNamedFlowThreadsNeedingLayout();
    187 
    188     if (needsTwoPassLayoutForAutoLogicalHeightRegions)
    189         flowThreadController()->resetRegionsOverrideLogicalContentHeight();
    190 
    191     layoutContent(state);
    192 
    193     if (needsTwoPassLayoutForAutoLogicalHeightRegions) {
    194         m_layoutPhase = ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions;
    195         flowThreadController()->markAutoLogicalHeightRegionsForLayout();
     212    if (checkTwoPassLayoutForAutoHeightRegions())
     213        layoutContentInAutoLogicalHeightRegions(state);
     214    else
    196215        layoutContent(state);
    197     }
    198216
    199217#ifndef NDEBUG
     
    10281046}
    10291047
     1048bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
     1049{
     1050    return hasRenderNamedFlowThreads() && m_flowThreadController->hasAutoLogicalHeightRegions();
     1051}
     1052
    10301053FlowThreadController* RenderView::flowThreadController()
    10311054{
  • trunk/Source/WebCore/rendering/RenderView.h

    r140291 r140400  
    207207   
    208208    bool hasRenderNamedFlowThreads() const;
     209    bool checkTwoPassLayoutForAutoHeightRegions() const;
    209210    FlowThreadController* flowThreadController();
    210211
     
    276277
    277278    void layoutContent(const LayoutState&);
     279    void layoutContentInAutoLogicalHeightRegions(const LayoutState&);
    278280#ifndef NDEBUG
    279281    void checkLayoutState(const LayoutState&);
Note: See TracChangeset for help on using the changeset viewer.