Changeset 144487 in webkit


Ignore:
Timestamp:
Mar 1, 2013 1:02:16 PM (11 years ago)
Author:
betravis@adobe.com
Message:

[css exclusions] setting shape-inside on a parent does not relayout child blocks' inline content
https://bugs.webkit.org/show_bug.cgi?id=108128

Reviewed by David Hyatt.

Source/WebCore:

Ensure that blocks lay out when their parent's shape-inside changes.
ExclusionShapeInsideInfo now stores an additional flag indicating whether
the shape has changed and its block's children require layout. Each block
can look up the flag via LayoutState to determine whether it needs to lay
out its children.

Test: fast/exclusions/shape-inside/shape-inside-dynamic-nested.html

  • rendering/ExclusionShapeInfo.h:

(WebCore::ExclusionShapeInfo::shapeSizeDirty): Add a method to determine
if the shape has changed.
(ExclusionShapeInfo):

  • rendering/ExclusionShapeInsideInfo.h:

(WebCore::ExclusionShapeInsideInfo::setNeedsLayout): Set the flag indicating
layout is necessary.
(WebCore::ExclusionShapeInsideInfo::needsLayout): Retrieve the layout flag.
(ExclusionShapeInsideInfo):
(WebCore::ExclusionShapeInsideInfo::ExclusionShapeInsideInfo): Initialize
the layout flag.

  • rendering/RenderBlock.cpp:

(WebCore::exclusionInfoRequiresRelayout): Return true if the shape info should
cause a relayout. Also update the needsLayout flag on the ExclusionShapeInsideInfo.
(WebCore):
(WebCore::RenderBlock::updateRegionsAndExclusionsLogicalSize): Return a boolean
indicating whether regions or exclusions updates should cause a relayout.
(WebCore::RenderBlock::layoutBlock): Relayout children if the shape inside has
changed.

  • rendering/RenderBlock.h:

(RenderBlock):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::layoutExclusionShapeInsideInfo): Changing to be a
class method.
(WebCore::LineWidth::LineWidth): Changing to use class method.
(WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Ditto.
(WebCore::constructBidiRunsForLine): Ditto.
(WebCore::RenderBlock::layoutRunsAndFloatsInRange): Ditto.
(WebCore::RenderBlock::LineBreaker::nextLineBreak): Ditto.

LayoutTests:

Test that setting and resetting shape-inside and shape-outside correctly lay out
content inside of child blocks.

  • fast/exclusions/shape-inside/shape-inside-dynamic-nested-expected.html: Added.
  • fast/exclusions/shape-inside/shape-inside-dynamic-nested.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r144485 r144487  
     12013-03-01  Bear Travis  <betravis@adobe.com>
     2
     3        [css exclusions] setting shape-inside on a parent does not relayout child blocks' inline content
     4        https://bugs.webkit.org/show_bug.cgi?id=108128
     5
     6        Reviewed by David Hyatt.
     7
     8        Test that setting and resetting shape-inside and shape-outside correctly lay out
     9        content inside of child blocks.
     10
     11        * fast/exclusions/shape-inside/shape-inside-dynamic-nested-expected.html: Added.
     12        * fast/exclusions/shape-inside/shape-inside-dynamic-nested.html: Added.
     13
    1142013-03-01  Uday Kiran  <udaykiran@motorola.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r144485 r144487  
     12013-03-01  Bear Travis  <betravis@adobe.com>
     2
     3        [css exclusions] setting shape-inside on a parent does not relayout child blocks' inline content
     4        https://bugs.webkit.org/show_bug.cgi?id=108128
     5
     6        Reviewed by David Hyatt.
     7
     8        Ensure that blocks lay out when their parent's shape-inside changes.
     9        ExclusionShapeInsideInfo now stores an additional flag indicating whether
     10        the shape has changed and its block's children require layout. Each block
     11        can look up the flag via LayoutState to determine whether it needs to lay
     12        out its children.
     13
     14        Test: fast/exclusions/shape-inside/shape-inside-dynamic-nested.html
     15
     16        * rendering/ExclusionShapeInfo.h:
     17        (WebCore::ExclusionShapeInfo::shapeSizeDirty): Add a method to determine
     18        if the shape has changed.
     19        (ExclusionShapeInfo):
     20        * rendering/ExclusionShapeInsideInfo.h:
     21        (WebCore::ExclusionShapeInsideInfo::setNeedsLayout): Set the flag indicating
     22        layout is necessary.
     23        (WebCore::ExclusionShapeInsideInfo::needsLayout): Retrieve the layout flag.
     24        (ExclusionShapeInsideInfo):
     25        (WebCore::ExclusionShapeInsideInfo::ExclusionShapeInsideInfo): Initialize
     26        the layout flag.
     27        * rendering/RenderBlock.cpp:
     28        (WebCore::exclusionInfoRequiresRelayout): Return true if the shape info should
     29        cause a relayout. Also update the needsLayout flag on the ExclusionShapeInsideInfo.
     30        (WebCore):
     31        (WebCore::RenderBlock::updateRegionsAndExclusionsLogicalSize): Return a boolean
     32        indicating whether regions or exclusions updates should cause a relayout.
     33        (WebCore::RenderBlock::layoutBlock): Relayout children if the shape inside has
     34        changed.
     35        * rendering/RenderBlock.h:
     36        (RenderBlock):
     37        * rendering/RenderBlockLineLayout.cpp:
     38        (WebCore::RenderBlock::layoutExclusionShapeInsideInfo): Changing to be a
     39        class method.
     40        (WebCore::LineWidth::LineWidth): Changing to use class method.
     41        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Ditto.
     42        (WebCore::constructBidiRunsForLine): Ditto.
     43        (WebCore::RenderBlock::layoutRunsAndFloatsInRange): Ditto.
     44        (WebCore::RenderBlock::LineBreaker::nextLineBreak): Ditto.
     45
    1462013-03-01  Uday Kiran  <udaykiran@motorola.com>
    247
  • trunk/Source/WebCore/rendering/ExclusionShapeInfo.h

    r143766 r144487  
    9393
    9494    void dirtyShapeSize() { m_shape.clear(); }
     95    bool shapeSizeDirty() { return !m_shape.get(); }
    9596    const RenderType* owner() const { return m_renderer; }
    9697
  • trunk/Source/WebCore/rendering/ExclusionShapeInsideInfo.h

    r143420 r144487  
    8787    LayoutUnit logicalLineBottom() const { return m_shapeLineTop + m_lineHeight + logicalTopOffset(); }
    8888
     89    void setNeedsLayout(bool value) { m_needsLayout = value; }
     90    bool needsLayout() { return m_needsLayout; }
     91
    8992private:
    90     ExclusionShapeInsideInfo(const RenderBlock* renderer) : ExclusionShapeInfo<RenderBlock, &RenderStyle::resolvedShapeInside>(renderer) { }
     93    ExclusionShapeInsideInfo(const RenderBlock* renderer)
     94    : ExclusionShapeInfo<RenderBlock, &RenderStyle::resolvedShapeInside> (renderer)
     95    , m_needsLayout(false)
     96    { }
    9197
    9298    LayoutUnit m_shapeLineTop;
     
    95101    SegmentList m_segments;
    96102    SegmentRangeList m_segmentRanges;
     103    bool m_needsLayout;
    97104};
    98105
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r144461 r144487  
    14151415#endif
    14161416
    1417 void RenderBlock::updateRegionsAndExclusionsLogicalSize()
     1417static inline bool exclusionInfoRequiresRelayout(const RenderBlock* block)
     1418{
     1419#if !ENABLE(CSS_EXCLUSIONS)
     1420    return false;
     1421#else
     1422    ExclusionShapeInsideInfo* info = block->exclusionShapeInsideInfo();
     1423    if (info)
     1424        info->setNeedsLayout(info->shapeSizeDirty());
     1425    else
     1426        info = block->layoutExclusionShapeInsideInfo();
     1427    return info && info->needsLayout();
     1428#endif
     1429}
     1430
     1431bool RenderBlock::updateRegionsAndExclusionsLogicalSize()
    14181432{
    14191433#if ENABLE(CSS_EXCLUSIONS)
     
    14221436    if (!inRenderFlowThread())
    14231437#endif
    1424         return;
     1438        return exclusionInfoRequiresRelayout(this);
    14251439
    14261440    LayoutUnit oldHeight = logicalHeight();
     
    14421456    setLogicalHeight(oldHeight);
    14431457    setLogicalTop(oldTop);
     1458   
     1459    return exclusionInfoRequiresRelayout(this);
    14441460}
    14451461
     
    15401556            relayoutChildren = true;
    15411557    }
    1542     updateRegionsAndExclusionsLogicalSize();
     1558
     1559    if (updateRegionsAndExclusionsLogicalSize())
     1560        relayoutChildren = true;
    15431561
    15441562    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r144364 r144487  
    448448#if ENABLE(CSS_EXCLUSIONS)
    449449    ExclusionShapeInsideInfo* exclusionShapeInsideInfo() const;
     450    ExclusionShapeInsideInfo* layoutExclusionShapeInsideInfo() const;
    450451    bool allowsExclusionShapeInsideInfoSharing() const { return !isInline() && !isFloating(); }
    451452#endif
     
    558559#endif
    559560
    560     void updateRegionsAndExclusionsLogicalSize();
     561    bool updateRegionsAndExclusionsLogicalSize();
    561562    void computeRegionRangeForBlock();
    562563
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r144073 r144487  
    7878
    7979#if ENABLE(CSS_EXCLUSIONS)
    80 static inline ExclusionShapeInsideInfo* layoutExclusionShapeInsideInfo(const RenderBlock* block)
    81 {
    82     ExclusionShapeInsideInfo* shapeInsideInfo = block->view()->layoutState()->exclusionShapeInsideInfo();
    83     if (!shapeInsideInfo && block->inRenderFlowThread()) {
    84         LayoutUnit offset = block->logicalHeight() + logicalHeightForLine(block, false);
    85         RenderRegion* region = block->regionAtBlockOffset(offset);
     80ExclusionShapeInsideInfo* RenderBlock::layoutExclusionShapeInsideInfo() const
     81{
     82    ExclusionShapeInsideInfo* shapeInsideInfo = view()->layoutState()->exclusionShapeInsideInfo();
     83    if (!shapeInsideInfo && inRenderFlowThread()) {
     84        LayoutUnit offset = logicalHeight() + logicalHeightForLine(this, false);
     85        RenderRegion* region = regionAtBlockOffset(offset);
    8686        return region ? region->exclusionShapeInsideInfo() : 0;
    8787    }
     
    107107        ASSERT(block);
    108108#if ENABLE(CSS_EXCLUSIONS)
    109         ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(m_block);
     109        ExclusionShapeInsideInfo* exclusionShapeInsideInfo = m_block->layoutExclusionShapeInsideInfo();
    110110        if (exclusionShapeInsideInfo)
    111111            m_segment = exclusionShapeInsideInfo->currentSegment();
     
    952952    bool needsWordSpacing;
    953953#if ENABLE(CSS_EXCLUSIONS)
    954     ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this);
     954    ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo();
    955955    if (exclusionShapeInsideInfo && exclusionShapeInsideInfo->hasSegments()) {
    956956        BidiRun* segmentStart = firstRun;
     
    12751275    constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
    12761276#else
    1277     ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(block);
     1277    ExclusionShapeInsideInfo* exclusionShapeInsideInfo = block->layoutExclusionShapeInsideInfo();
    12781278    if (!exclusionShapeInsideInfo || !exclusionShapeInsideInfo->hasSegments()) {
    12791279        constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
     
    15411541#if ENABLE(CSS_EXCLUSIONS)
    15421542    LayoutUnit absoluteLogicalTop;
    1543     ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this);
     1543    ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo();
    15441544    if (exclusionShapeInsideInfo) {
    15451545        ASSERT(exclusionShapeInsideInfo->owner() == this || allowsExclusionShapeInsideInfoSharing());
     
    15771577        // case these segments may be incorrect.
    15781578        if (inRenderFlowThread())
    1579             exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this);
     1579            exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo();
    15801580        if (exclusionShapeInsideInfo) {
    15811581            LayoutUnit lineTop = logicalHeight() + absoluteLogicalTop;
     
    25422542    return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
    25432543#else
    2544     ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(m_block);
     2544    ExclusionShapeInsideInfo* exclusionShapeInsideInfo = m_block->layoutExclusionShapeInsideInfo();
    25452545    if (!exclusionShapeInsideInfo || !exclusionShapeInsideInfo->hasSegments())
    25462546        return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
Note: See TracChangeset for help on using the changeset viewer.