Changeset 111652 in webkit


Ignore:
Timestamp:
Mar 21, 2012 9:58:22 PM (12 years ago)
Author:
mitz@apple.com
Message:

REGRESSION (r111635): Assertion failure in RenderFlexibleBox::layoutFlexItems() (!lineContexts.size()) in many flexbox tests
https://bugs.webkit.org/show_bug.cgi?id=81870

Reverted r111635, the fix for bug 81843.

  • rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::WrapReverseContext::WrapReverseContext):
(WebCore::RenderFlexibleBox::WrapReverseContext::addCrossAxisOffset):
(RenderFlexibleBox::WrapReverseContext):
(WebCore::RenderFlexibleBox::WrapReverseContext::addNumberOfChildrenOnLine):
(WebCore::RenderFlexibleBox::WrapReverseContext::lineCrossAxisDelta):
(WebCore::RenderFlexibleBox::layoutFlexItems):
(WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
(WebCore::RenderFlexibleBox::alignChildren):
(WebCore::RenderFlexibleBox::flipForWrapReverse):

  • rendering/RenderFlexibleBox.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r111648 r111652  
     12012-03-21  Dan Bernstein  <mitz@apple.com>
     2
     3        REGRESSION (r111635): Assertion failure in RenderFlexibleBox::layoutFlexItems() (!lineContexts.size()) in many flexbox tests
     4        https://bugs.webkit.org/show_bug.cgi?id=81870
     5
     6        Reverted r111635, the fix for bug 81843.
     7
     8        * rendering/RenderFlexibleBox.cpp:
     9        (WebCore::RenderFlexibleBox::WrapReverseContext::WrapReverseContext):
     10        (WebCore::RenderFlexibleBox::WrapReverseContext::addCrossAxisOffset):
     11        (RenderFlexibleBox::WrapReverseContext):
     12        (WebCore::RenderFlexibleBox::WrapReverseContext::addNumberOfChildrenOnLine):
     13        (WebCore::RenderFlexibleBox::WrapReverseContext::lineCrossAxisDelta):
     14        (WebCore::RenderFlexibleBox::layoutFlexItems):
     15        (WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
     16        (WebCore::RenderFlexibleBox::alignChildren):
     17        (WebCore::RenderFlexibleBox::flipForWrapReverse):
     18        * rendering/RenderFlexibleBox.h:
     19
    1202012-03-21  Emil A Eklund  <eae@chromium.org>
    221
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r111635 r111652  
    103103};
    104104
    105 struct RenderFlexibleBox::LineContext {
    106     LineContext(LayoutUnit crossAxisOffset, LayoutUnit crossAxisExtent, size_t numberOfChildren, LayoutUnit maxAscent)
    107         : crossAxisOffset(crossAxisOffset)
    108         , crossAxisExtent(crossAxisExtent)
    109         , numberOfChildren(numberOfChildren)
    110         , maxAscent(maxAscent)
     105struct RenderFlexibleBox::WrapReverseContext {
     106    explicit WrapReverseContext(EFlexWrap flexWrap)
     107        : isWrapReverse(flexWrap == FlexWrapReverse)
    111108    {
    112109    }
    113110
    114     LayoutUnit crossAxisOffset;
    115     LayoutUnit crossAxisExtent;
    116     size_t numberOfChildren;
    117     LayoutUnit maxAscent;
     111    void addCrossAxisOffset(LayoutUnit offset)
     112    {
     113        if (!isWrapReverse)
     114            return;
     115        crossAxisOffsets.append(offset);
     116    }
     117
     118    void addNumberOfChildrenOnLine(size_t numberOfChildren)
     119    {
     120        if (!isWrapReverse)
     121            return;
     122        childrenPerLine.append(numberOfChildren);
     123    }
     124
     125    LayoutUnit lineCrossAxisDelta(size_t line, LayoutUnit crossAxisContentExtent) const
     126    {
     127        ASSERT(line + 1 < crossAxisOffsets.size());
     128        LayoutUnit lineHeight = crossAxisOffsets[line + 1] - crossAxisOffsets[line];
     129        LayoutUnit originalOffset = crossAxisOffsets[line] - crossAxisOffsets[0];
     130        LayoutUnit newOffset = crossAxisContentExtent - originalOffset - lineHeight;
     131        return newOffset - originalOffset;
     132    }
     133
     134    WTF::Vector<LayoutUnit> crossAxisOffsets;
     135    WTF::Vector<size_t> childrenPerLine;
     136    bool isWrapReverse;
    118137};
    119138
     
    589608    float totalNegativeFlexibility;
    590609    LayoutUnit minMaxAppliedMainAxisExtent;
    591     WTF::Vector<LineContext> lineContexts;
    592610    FlexOrderIterator flexIterator(this, flexOrderValues);
     611
     612    // For wrap-reverse, we need to layout as wrap, then reverse the lines. The next two arrays
     613    // are some extra information so it's possible to reverse the lines.
     614    WrapReverseContext wrapReverseContext(style()->flexWrap());
    593615
    594616    LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
     
    603625        }
    604626
    605         layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, lineContexts);
    606     }
    607 
    608     ASSERT(!lineContexts.size());
    609     alignChildren(flexIterator, lineContexts);
    610 
    611     if (style()->flexWrap() == FlexWrapReverse)
    612         flipForWrapReverse(flexIterator, lineContexts);
     627        wrapReverseContext.addNumberOfChildrenOnLine(orderedChildren.size());
     628        wrapReverseContext.addCrossAxisOffset(crossAxisOffset);
     629        layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace);
     630    }
     631
     632    if (wrapReverseContext.isWrapReverse) {
     633        wrapReverseContext.addCrossAxisOffset(crossAxisOffset);
     634        flipForWrapReverse(flexIterator, wrapReverseContext);
     635    }
    613636
    614637    // direction:rtl + flex-direction:column means the cross-axis direction is flipped.
     
    846869}
    847870
    848 void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts)
     871void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
    849872{
    850873    LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart();
     
    908931
    909932    LayoutUnit lineCrossAxisExtent = isMultiline() ? maxChildCrossAxisExtent : crossAxisContentExtent();
    910     lineContexts.append(LineContext(crossAxisOffset, lineCrossAxisExtent, children.size(), maxAscent));
     933    alignChildren(children, lineCrossAxisExtent, maxAscent);
     934
    911935    crossAxisOffset += lineCrossAxisExtent;
    912936}
     
    953977}
    954978
    955 void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts)
    956 {
    957     // Keep track of the space between the baseline edge and the after edge of the box for each line.
    958     WTF::Vector<LayoutUnit> minMarginAfterBaselines;
    959 
    960     RenderBox* child = iterator.first();
    961     for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
    962         LayoutUnit minMarginAfterBaseline = std::numeric_limits<LayoutUnit>::max();
    963         LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
    964         LayoutUnit maxAscent = lineContexts[lineNumber].maxAscent;
    965 
    966         for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
    967             switch (flexAlignForChild(child)) {
    968             case AlignAuto:
    969                 ASSERT_NOT_REACHED();
    970                 break;
    971             case AlignStretch: {
    972                 applyStretchAlignmentToChild(child, lineCrossAxisExtent);
    973                 // Since wrap-reverse flips cross start and cross end, strech children should be aligned with the cross end.
    974                 if (style()->flexWrap() == FlexWrapReverse)
    975                     adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
    976                 break;
    977             }
    978             case AlignStart:
    979                 break;
    980             case AlignEnd:
     979void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent)
     980{
     981    LayoutUnit minMarginAfterBaseline = std::numeric_limits<LayoutUnit>::max();
     982
     983    for (size_t i = 0; i < children.size(); ++i) {
     984        RenderBox* child = children[i];
     985        switch (flexAlignForChild(child)) {
     986        case AlignAuto:
     987            ASSERT_NOT_REACHED();
     988            break;
     989        case AlignStretch: {
     990            applyStretchAlignmentToChild(child, lineCrossAxisExtent);
     991            // Since wrap-reverse flips cross start and cross end, strech children should be aligned with the cross end.
     992            if (style()->flexWrap() == FlexWrapReverse)
    981993                adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
    982                 break;
    983             case AlignCenter:
    984                 adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
    985                 break;
    986             case AlignBaseline: {
    987                 LayoutUnit ascent = marginBoxAscentForChild(child);
    988                 LayoutUnit startOffset = maxAscent - ascent;
    989                 adjustAlignmentForChild(child, startOffset);
    990 
    991                 if (style()->flexWrap() == FlexWrapReverse)
    992                     minMarginAfterBaseline = std::min(minMarginAfterBaseline, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) - startOffset);
    993                 break;
    994             }
    995             }
    996         }
    997         minMarginAfterBaselines.append(minMarginAfterBaseline);
    998     }
    999 
    1000     if (style()->flexWrap() != FlexWrapReverse)
    1001         return;
     994            break;
     995        }
     996        case AlignStart:
     997            break;
     998        case AlignEnd:
     999            adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
     1000            break;
     1001        case AlignCenter:
     1002            adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
     1003            break;
     1004        case AlignBaseline: {
     1005            LayoutUnit ascent = marginBoxAscentForChild(child);
     1006            LayoutUnit startOffset = maxAscent - ascent;
     1007            adjustAlignmentForChild(child, startOffset);
     1008
     1009            if (style()->flexWrap() == FlexWrapReverse)
     1010                minMarginAfterBaseline = std::min(minMarginAfterBaseline, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) - startOffset);
     1011            break;
     1012        }
     1013        }
     1014    }
    10021015
    10031016    // wrap-reverse flips the cross axis start and end. For baseline alignment, this means we
    10041017    // need to align the after edge of baseline elements with the after edge of the flex line.
    1005     child = iterator.first();
    1006     for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
    1007         LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber];
    1008         for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
    1009             if (flexAlignForChild(child) == AlignBaseline && minMarginAfterBaseline)
     1018    if (style()->flexWrap() == FlexWrapReverse && minMarginAfterBaseline) {
     1019        for (size_t i = 0; i < children.size(); ++i) {
     1020            RenderBox* child = children[i];
     1021            if (flexAlignForChild(child) == AlignBaseline)
    10101022                adjustAlignmentForChild(child, minMarginAfterBaseline);
    10111023        }
     
    10521064}
    10531065
    1054 void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts)
     1066void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WrapReverseContext& wrapReverseContext)
    10551067{
    10561068    if (!isColumnFlow())
    10571069        computeLogicalHeight();
    10581070
     1071    size_t currentChild = 0;
     1072    size_t lineNumber = 0;
    10591073    LayoutUnit contentExtent = crossAxisContentExtent();
    1060     RenderBox* child = iterator.first();
    1061     for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
    1062         for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
    1063             LayoutPoint location = flowAwareLocationForChild(child);
    1064             LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
    1065             LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - lineContexts[0].crossAxisOffset;
    1066             LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxisExtent;
    1067             location.setY(location.y() + newOffset - originalOffset);
    1068 
    1069             LayoutRect oldRect = child->frameRect();
    1070             setFlowAwareLocationForChild(child, location);
    1071             if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
    1072                 child->repaintDuringLayoutIfMoved(oldRect);
    1073         }
    1074     }
    1075 }
    1076 
    1077 }
     1074    for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
     1075        LayoutPoint location = flowAwareLocationForChild(child);
     1076        location.setY(location.y() + wrapReverseContext.lineCrossAxisDelta(lineNumber, contentExtent));
     1077
     1078        LayoutRect oldRect = child->frameRect();
     1079        setFlowAwareLocationForChild(child, location);
     1080        if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
     1081            child->repaintDuringLayoutIfMoved(oldRect);
     1082
     1083        if (++currentChild == wrapReverseContext.childrenPerLine[lineNumber]) {
     1084            ++lineNumber;
     1085            currentChild = 0;
     1086        }
     1087    }
     1088}
     1089
     1090}
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.h

    r111635 r111652  
    6262    typedef WTF::Vector<RenderBox*> OrderedFlexItemList;
    6363
    64     struct LineContext;
     64    struct WrapReverseContext;
    6565
    6666    bool hasOrthogonalFlow(RenderBox* child) const;
     
    115115    void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
    116116    void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
    117     void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts);
     117    void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
    118118    void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
    119     void alignChildren(FlexOrderIterator&, const WTF::Vector<LineContext>&);
     119    void alignChildren(const OrderedFlexItemList&, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent);
    120120    void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent);
    121121    void flipForRightToLeftColumn(FlexOrderIterator&);
    122     void flipForWrapReverse(FlexOrderIterator&, const WTF::Vector<LineContext>&);
     122    void flipForWrapReverse(FlexOrderIterator&, const WrapReverseContext&);
    123123};
    124124
Note: See TracChangeset for help on using the changeset viewer.