diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-25 15:09:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-25 15:09:11 +0200 |
commit | a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd (patch) | |
tree | b7abd9f49ae1d4d2e426a5883bfccd42b8e2ee12 /Source/WebCore/rendering/RenderFlexibleBox.cpp | |
parent | 8d473cf9743f1d30a16a27114e93bd5af5648d23 (diff) | |
download | qtwebkit-a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd.tar.gz |
Imported WebKit commit eb5c1b8fe4d4b1b90b5137433fc58a91da0e6878 (http://svn.webkit.org/repository/webkit/trunk@118516)
Diffstat (limited to 'Source/WebCore/rendering/RenderFlexibleBox.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderFlexibleBox.cpp | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp index efa2eb71d..2feab4f75 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp @@ -642,12 +642,99 @@ void RenderFlexibleBox::layoutFlexItems(FlexOrderIterator& iterator, WTF::Vector } } +LayoutUnit RenderFlexibleBox::autoMarginOffsetInMainAxis(const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace) +{ + if (availableFreeSpace <= 0) + return 0; + + int numberOfAutoMargins = 0; + bool isHorizontal = isHorizontalFlow(); + for (size_t i = 0; i < children.size(); ++i) { + RenderBox* child = children[i]; + if (child->isPositioned()) + continue; + if (isHorizontal) { + if (child->style()->marginLeft().isAuto()) + ++numberOfAutoMargins; + if (child->style()->marginRight().isAuto()) + ++numberOfAutoMargins; + } else { + if (child->style()->marginTop().isAuto()) + ++numberOfAutoMargins; + if (child->style()->marginBottom().isAuto()) + ++numberOfAutoMargins; + } + } + if (!numberOfAutoMargins) + return 0; + + LayoutUnit sizeOfAutoMargin = availableFreeSpace / numberOfAutoMargins; + availableFreeSpace = 0; + return sizeOfAutoMargin; +} + +void RenderFlexibleBox::updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset) +{ + if (isHorizontalFlow()) { + if (child->style()->marginLeft().isAuto()) + child->setMarginLeft(autoMarginOffset); + if (child->style()->marginRight().isAuto()) + child->setMarginRight(autoMarginOffset); + } else { + if (child->style()->marginTop().isAuto()) + child->setMarginTop(autoMarginOffset); + if (child->style()->marginBottom().isAuto()) + child->setMarginBottom(autoMarginOffset); + } +} + +bool RenderFlexibleBox::hasAutoMarginsInCrossAxis(RenderBox* child) +{ + if (isHorizontalFlow()) + return child->style()->marginTop().isAuto() || child->style()->marginBottom().isAuto(); + return child->style()->marginLeft().isAuto() || child->style()->marginRight().isAuto(); +} + LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox* child) { LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child); return lineCrossAxisExtent - childCrossExtent; } +bool RenderFlexibleBox::updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace) +{ + bool isHorizontal = isHorizontalFlow(); + Length start = isHorizontal ? child->style()->marginTop() : child->style()->marginLeft(); + Length end = isHorizontal ? child->style()->marginBottom() : child->style()->marginRight(); + if (start.isAuto() && end.isAuto()) { + adjustAlignmentForChild(child, availableAlignmentSpace / 2); + if (isHorizontal) { + child->setMarginTop(availableAlignmentSpace / 2); + child->setMarginBottom(availableAlignmentSpace / 2); + } else { + child->setMarginLeft(availableAlignmentSpace / 2); + child->setMarginRight(availableAlignmentSpace / 2); + } + return true; + } + if (start.isAuto()) { + adjustAlignmentForChild(child, availableAlignmentSpace); + if (isHorizontal) + child->setMarginTop(availableAlignmentSpace); + else + child->setMarginLeft(availableAlignmentSpace); + return true; + } + if (end.isAuto()) { + if (isHorizontal) + child->setMarginBottom(availableAlignmentSpace); + else + child->setMarginRight(availableAlignmentSpace); + return true; + } + return false; +} + LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox* child) { LayoutUnit ascent = child->firstLineBoxBaseline(); @@ -673,9 +760,8 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Fle child->layoutIfNeeded(); } - // We set the margins because we want to make sure 'auto' has a margin - // of 0 and because if we're not auto sizing, we don't do a layout that - // computes the start/end margins. + // Before running the flex algorithm, 'auto' has a margin of 0. + // Also, if we're not auto sizing, we don't do a layout that computes the start/end margins. if (isHorizontalFlow()) { child->setMarginLeft(minimumValueForLength(child->style()->marginLeft(), flexboxAvailableContentExtent, renderView)); child->setMarginRight(minimumValueForLength(child->style()->marginRight(), flexboxAvailableContentExtent, renderView)); @@ -881,6 +967,8 @@ static EFlexAlign flexAlignForChild(RenderBox* child) void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts) { ASSERT(childSizes.size() == children.size()); + + LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, availableFreeSpace); LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart(); mainAxisOffset += initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size()); if (style()->flexDirection() == FlowRowReverse) @@ -902,8 +990,10 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons child->setChildNeedsLayout(true); child->layoutIfNeeded(); + updateAutoMarginsInMainAxis(child, autoMarginOffset); + LayoutUnit childCrossAxisMarginBoxExtent; - if (flexAlignForChild(child) == AlignBaseline) { + if (flexAlignForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child)) { LayoutUnit ascent = marginBoxAscentForChild(child); LayoutUnit descent = (crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child)) - ascent; @@ -1047,6 +1137,9 @@ void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, const WTF::Ve for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) { ASSERT(child); + if (updateAutoMarginsInCrossAxis(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child))) + continue; + switch (flexAlignForChild(child)) { case AlignAuto: ASSERT_NOT_REACHED(); @@ -1090,7 +1183,7 @@ void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, const WTF::Ve LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber]; for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) { ASSERT(child); - if (flexAlignForChild(child) == AlignBaseline && minMarginAfterBaseline) + if (flexAlignForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child) && minMarginAfterBaseline) adjustAlignmentForChild(child, minMarginAfterBaseline); } } |