Title: [201516] trunk
Revision
201516
Author
hy...@apple.com
Date
2016-05-31 11:42:17 -0700 (Tue, 31 May 2016)

Log Message

REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
https://bugs.webkit.org/show_bug.cgi?id=158040

Reviewed by Zalan Bujtas.

Source/WebCore:

Added new tests in fast/flexbox.

* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::clientLogicalBottomAfterRepositioning):
(WebCore::RenderFlexibleBox::hasOrthogonalFlow):
(WebCore::RenderFlexibleBox::mainAxisContentExtent):
(WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
(WebCore::RenderFlexibleBox::mainAxisBorderAndPaddingExtentForChild):
(WebCore::RenderFlexibleBox::mainAxisLengthIsDefinite):
(WebCore::RenderFlexibleBox::mainAxisScrollbarExtentForChild):
(WebCore::RenderFlexibleBox::prepareOrderIteratorAndMargins):
(WebCore::RenderFlexibleBox::crossAxisLengthIsDefinite):
(WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing):
(WebCore::RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax):
(WebCore::RenderFlexibleBox::useChildAspectRatio):
(WebCore::RenderFlexibleBox::adjustChildSizeForMinAndMax):
(WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis):
(WebCore::RenderFlexibleBox::mainAxisOverflowForChild):
(WebCore::RenderFlexibleBox::mainAxisExtentIsDefinite): Deleted.
(WebCore::RenderFlexibleBox::mainAxisLengthIsIndefinite): Deleted.
* rendering/RenderFlexibleBox.h:
(WebCore::RenderFlexibleBox::isFlexibleBoxImpl):

LayoutTests:

* fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html: Added.
* fast/flexbox/aspect-ratio-intrinsic-adjust.html: Added.
* fast/flexbox/resources/subjects_sm.png: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (201515 => 201516)


--- trunk/LayoutTests/ChangeLog	2016-05-31 17:53:20 UTC (rev 201515)
+++ trunk/LayoutTests/ChangeLog	2016-05-31 18:42:17 UTC (rev 201516)
@@ -1,3 +1,14 @@
+2016-05-31  Dave Hyatt  <hy...@apple.com>
+
+        REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
+        https://bugs.webkit.org/show_bug.cgi?id=158040
+
+        Reviewed by Zalan Bujtas.
+
+        * fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html: Added.
+        * fast/flexbox/aspect-ratio-intrinsic-adjust.html: Added.
+        * fast/flexbox/resources/subjects_sm.png: Added.
+
 2016-05-25  Sergio Villar Senin  <svil...@igalia.com>
 
         [css-grid] Empty grid without explicit tracks shouldn't have any size

Added: trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html (0 => 201516)


--- trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html	2016-05-31 18:42:17 UTC (rev 201516)
@@ -0,0 +1,47 @@
+<!doctype html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8" />
+    <title>img.weird-stretch</title>
+    <style>
+    body {
+    	width: 400px;
+    	margin: 0 auto;
+    }
+    .weird-stretch-container {
+        float: right;
+        width: 400px;
+        height: 250px;
+        display: -webkit-flex;
+        display: -ms-flexbox;
+        display: flex;
+        -webkit-box-align: center;
+        -webkit-align-items: center;
+        -ms-flex-align: center;
+        align-items: center;
+        -webkit-box-pack: center;
+        -webkit-justify-content: center;
+        -ms-flex-pack: center;
+        justify-content: center
+    }
+    
+    </style>
+</head>
+
+<body>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" width="100px" />
+    </div>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" width="63px" />
+    </div>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" width="132px" height="210px" />
+    </div>
+</body>
+
+</html>

Added: trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust.html (0 => 201516)


--- trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust.html	                        (rev 0)
+++ trunk/LayoutTests/fast/flexbox/aspect-ratio-intrinsic-adjust.html	2016-05-31 18:42:17 UTC (rev 201516)
@@ -0,0 +1,51 @@
+<!doctype html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8" />
+    <title>img.weird-stretch</title>
+    <style>
+    body {
+    	width: 400px;
+    	margin: 0 auto;
+    }
+    .weird-stretch-container {
+        float: right;
+        width: 400px;
+        height: 250px;
+        display: -webkit-flex;
+        display: -ms-flexbox;
+        display: flex;
+        -webkit-box-align: center;
+        -webkit-align-items: center;
+        -ms-flex-align: center;
+        align-items: center;
+        -webkit-box-pack: center;
+        -webkit-justify-content: center;
+        -ms-flex-pack: center;
+        justify-content: center
+    }
+    
+    img.weird-stretch {
+        max-width: 100%;
+        max-height: 100%
+    }
+    </style>
+</head>
+
+<body>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" width="100px" />
+    </div>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" height="100px" />
+    </div>
+
+    <div class="weird-stretch-container">
+        <img class="weird-stretch" alt="" src="" width="132px" height="210px" />
+    </div>
+</body>
+
+</html>

Added: trunk/LayoutTests/fast/flexbox/resources/subjects_sm.png


(Binary files differ)
Property changes on: trunk/LayoutTests/fast/flexbox/resources/subjects_sm.png ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/Source/WebCore/ChangeLog (201515 => 201516)


--- trunk/Source/WebCore/ChangeLog	2016-05-31 17:53:20 UTC (rev 201515)
+++ trunk/Source/WebCore/ChangeLog	2016-05-31 18:42:17 UTC (rev 201516)
@@ -1,3 +1,33 @@
+2016-05-31  Dave Hyatt  <hy...@apple.com>
+
+        REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
+        https://bugs.webkit.org/show_bug.cgi?id=158040
+
+        Reviewed by Zalan Bujtas.
+
+        Added new tests in fast/flexbox.
+
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::clientLogicalBottomAfterRepositioning):
+        (WebCore::RenderFlexibleBox::hasOrthogonalFlow):
+        (WebCore::RenderFlexibleBox::mainAxisContentExtent):
+        (WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
+        (WebCore::RenderFlexibleBox::mainAxisBorderAndPaddingExtentForChild):
+        (WebCore::RenderFlexibleBox::mainAxisLengthIsDefinite):
+        (WebCore::RenderFlexibleBox::mainAxisScrollbarExtentForChild):
+        (WebCore::RenderFlexibleBox::prepareOrderIteratorAndMargins):
+        (WebCore::RenderFlexibleBox::crossAxisLengthIsDefinite):
+        (WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing):
+        (WebCore::RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax):
+        (WebCore::RenderFlexibleBox::useChildAspectRatio):
+        (WebCore::RenderFlexibleBox::adjustChildSizeForMinAndMax):
+        (WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis):
+        (WebCore::RenderFlexibleBox::mainAxisOverflowForChild):
+        (WebCore::RenderFlexibleBox::mainAxisExtentIsDefinite): Deleted.
+        (WebCore::RenderFlexibleBox::mainAxisLengthIsIndefinite): Deleted.
+        * rendering/RenderFlexibleBox.h:
+        (WebCore::RenderFlexibleBox::isFlexibleBoxImpl):
+
 2016-05-31  Alex Christensen  <achristen...@webkit.org>
 
         Build fix after r201482.

Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (201515 => 201516)


--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp	2016-05-31 17:53:20 UTC (rev 201515)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp	2016-05-31 18:42:17 UTC (rev 201516)
@@ -367,7 +367,7 @@
     return std::max(clientLogicalBottom(), maxChildLogicalBottom);
 }
 
-bool RenderFlexibleBox::hasOrthogonalFlow(RenderBox& child) const
+bool RenderFlexibleBox::hasOrthogonalFlow(const RenderBox& child) const
 {
     // FIXME: If the child is a flexbox, then we need to check isHorizontalFlow.
     return isHorizontalFlow() != child.isHorizontalWritingMode();
@@ -454,14 +454,14 @@
     return contentLogicalWidth();
 }
 
-Optional<LayoutUnit> RenderFlexibleBox::computeMainAxisExtentForChild(RenderBox& child, SizeType sizeType, const Length& size)
+Optional<LayoutUnit> RenderFlexibleBox::computeMainAxisExtentForChild(const RenderBox& child, SizeType sizeType, const Length& size)
 {
     // FIXME: This is wrong for orthogonal flows. It should use the flexbox's writing-mode, not the child's in order
     // to figure out the logical height/width.
     if (isColumnFlow()) {
         // We don't have to check for "auto" here - computeContentLogicalHeight will just return Nullopt for that case anyway.
         if (size.isIntrinsic())
-            child.layoutIfNeeded();
+            const_cast<RenderBox&>(child).layoutIfNeeded(); // FIXME: Should not need to do a layout here.
         return child.computeContentLogicalHeight(sizeType, size, child.logicalHeight() - child.borderAndPaddingLogicalHeight());
     }
     // FIXME: Figure out how this should work for regions and pass in the appropriate values.
@@ -652,17 +652,16 @@
 {
     return isHorizontalFlow() ? child.horizontalBorderAndPaddingExtent() : child.verticalBorderAndPaddingExtent();
 }
-
-bool RenderFlexibleBox::mainAxisExtentIsDefinite() const
+    
+bool RenderFlexibleBox::mainAxisLengthIsDefinite(const RenderBox& child, const Length& flexBasis) const
 {
-    return isColumnFlow() ? hasDefiniteLogicalHeight() : hasDefiniteLogicalWidth();
+    if (flexBasis.isAuto())
+        return false;
+    if (flexBasis.isPercentOrCalculated())
+        return isColumnFlow() ? bool(child.computePercentageLogicalHeight(flexBasis)) : hasDefiniteLogicalWidth();
+    return true;
 }
 
-bool RenderFlexibleBox::mainAxisLengthIsIndefinite(const Length& flexBasis) const
-{
-    return flexBasis.isAuto() || (flexBasis.isPercentOrCalculated() && !mainAxisExtentIsDefinite());
-}
-
 LayoutUnit RenderFlexibleBox::mainAxisScrollbarExtentForChild(RenderBox& child) const
 {
     return isHorizontalFlow() ? child.verticalScrollbarWidth() : child.horizontalScrollbarHeight();
@@ -859,19 +858,84 @@
     }
 }
 
-LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox& child, LayoutUnit childSize)
+bool RenderFlexibleBox::crossAxisLengthIsDefinite(const RenderBox& child, const Length& length) const
 {
+    if (length.isAuto())
+        return false;
+    if (length.isPercentOrCalculated())
+        return hasOrthogonalFlow(child) ? hasDefiniteLogicalWidth() : bool(child.computePercentageLogicalHeight(length));
+    return length.isFixed();
+}
+
+    
+Optional<LayoutUnit> RenderFlexibleBox::computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const
+{
+    ASSERT(child.hasAspectRatio());
+    ASSERT(child.intrinsicSize().height() > 0);
+    
+    Optional<LayoutUnit> crossSize;
+    if (crossSizeLength.isFixed())
+        crossSize = LayoutUnit(crossSizeLength.value());
+    else {
+        ASSERT(crossSizeLength.isPercentOrCalculated());
+        crossSize = hasOrthogonalFlow(child) ?
+        adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(crossSizeLength, contentWidth())) :
+        child.computePercentageLogicalHeight(crossSizeLength);
+    }
+    
+    if (!crossSize)
+        return crossSize;
+
+    const LayoutSize& childIntrinsicSize = child.intrinsicSize();
+    double ratio = childIntrinsicSize.width().toFloat() / childIntrinsicSize.height().toFloat();
+    if (isHorizontalFlow())
+        return LayoutUnit(crossSize.value() * ratio);
+    return LayoutUnit(crossSize.value() / ratio);
+}
+
+LayoutUnit RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax(const RenderBox& child, LayoutUnit childSize)
+{
+    Length crossMin = isHorizontalFlow() ? child.style().minHeight() : child.style().minWidth();
+    Length crossMax = isHorizontalFlow() ? child.style().maxHeight() : child.style().maxWidth();
+
+    if (crossAxisLengthIsDefinite(child, crossMax)) {
+        Optional<LayoutUnit> maxValue = computeMainSizeFromAspectRatioUsing(child, crossMax);
+        if (maxValue)
+            childSize = std::min(maxValue.value(), childSize);
+    }
+    
+    if (crossAxisLengthIsDefinite(child, crossMin)) {
+        Optional<LayoutUnit> minValue = computeMainSizeFromAspectRatioUsing(child, crossMin);
+        if (minValue)
+            childSize = std::max(minValue.value(), childSize);
+    }
+    
+    return childSize;
+}
+
+bool RenderFlexibleBox::useChildAspectRatio(const RenderBox& child) const
+{
+    if (!child.hasAspectRatio())
+        return false;
+    if (!child.intrinsicSize().height())
+        return false;
+    Length crossSize = isHorizontalFlow() ? child.style().height() : child.style().width();
+    return crossAxisLengthIsDefinite(child, crossSize);
+}
+
+LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(const RenderBox& child, LayoutUnit childSize)
+{
     Length max = isHorizontalFlow() ? child.style().maxWidth() : child.style().maxHeight();
     Optional<LayoutUnit> maxExtent = Nullopt;
     if (max.isSpecifiedOrIntrinsic()) {
         maxExtent = computeMainAxisExtentForChild(child, MaxSize, max);
         childSize = std::min(childSize, maxExtent.valueOr(childSize));
     }
-
+    
     Length min = isHorizontalFlow() ? child.style().minWidth() : child.style().minHeight();
     if (min.isSpecifiedOrIntrinsic())
         return std::max(childSize, computeMainAxisExtentForChild(child, MinSize, min).valueOr(childSize));
-
+    
     if (!isFlexibleBoxImpl() && min.isAuto() && mainAxisOverflowForChild(child) == OVISIBLE && !(isColumnFlow() && is<RenderFlexibleBox>(child))) {
         // This is the implementation of CSS flexbox section 4.5 which defines the minimum size of "pure" flex
         // items. For any other item the value should be 0, this also includes RenderFlexibleBox's derived clases
@@ -880,15 +944,23 @@
         // size handling from the flex box spec first (4.5).
         LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, Length(MinContent)).value();
         ASSERT(contentSize >= 0);
+        if (child.hasAspectRatio() && child.intrinsicSize().height() > 0)
+            contentSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize);
         contentSize = std::min(contentSize, maxExtent.valueOr(contentSize));
-
+        
         Length mainSize = isHorizontalFlow() ? child.style().width() : child.style().height();
-        if (!mainAxisLengthIsIndefinite(mainSize)) {
+        if (mainAxisLengthIsDefinite(child, mainSize)) {
             LayoutUnit resolvedMainSize = computeMainAxisExtentForChild(child, MainOrPreferredSize, mainSize).value();
             ASSERT(resolvedMainSize >= 0);
             LayoutUnit specifiedSize = std::min(resolvedMainSize, maxExtent.valueOr(resolvedMainSize));
-
             return std::max(childSize, std::min(specifiedSize, contentSize));
+        } else if (useChildAspectRatio(child)) {
+            Length crossSizeLength = isHorizontalFlow() ? child.style().height() : child.style().width();
+            Optional<LayoutUnit> transferredSize = computeMainSizeFromAspectRatioUsing(child, crossSizeLength);
+            if (transferredSize) {
+                transferredSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, transferredSize.value());
+                return std::max(childSize, std::min(transferredSize.value(), contentSize));
+            }
         }
         return std::max(childSize, contentSize);
     }
@@ -1091,7 +1163,7 @@
         child.updateLogicalHeight();
 }
 
-EOverflow RenderFlexibleBox::mainAxisOverflowForChild(RenderBox& child) const
+EOverflow RenderFlexibleBox::mainAxisOverflowForChild(const RenderBox& child) const
 {
     if (isHorizontalFlow())
         return child.style().overflowX();

Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (201515 => 201516)


--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h	2016-05-31 17:53:20 UTC (rev 201515)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h	2016-05-31 18:42:17 UTC (rev 201516)
@@ -86,7 +86,7 @@
     typedef Vector<LayoutRect, 8> ChildFrameRects;
 
     bool isFlexibleBox() const final { return true; }
-    bool hasOrthogonalFlow(RenderBox& child) const;
+    bool hasOrthogonalFlow(const RenderBox& child) const;
     bool isColumnFlow() const;
     bool isLeftToRightFlow() const;
     bool isMultiline() const;
@@ -98,7 +98,7 @@
     LayoutUnit mainAxisExtent() const;
     LayoutUnit crossAxisContentExtent() const;
     LayoutUnit mainAxisContentExtent(LayoutUnit contentLogicalHeight);
-    Optional<LayoutUnit> computeMainAxisExtentForChild(RenderBox& child, SizeType, const Length& size);
+    Optional<LayoutUnit> computeMainAxisExtentForChild(const RenderBox& child, SizeType, const Length& size);
     WritingMode transformedWritingMode() const;
     LayoutUnit flowAwareBorderStart() const;
     LayoutUnit flowAwareBorderEnd() const;
@@ -122,7 +122,7 @@
     LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox& child) const;
     LayoutUnit mainAxisScrollbarExtentForChild(RenderBox& child) const;
     LayoutUnit preferredMainAxisContentExtentForChild(RenderBox& child, bool hasInfiniteLineLength);
-    EOverflow mainAxisOverflowForChild(RenderBox&) const;
+    EOverflow mainAxisOverflowForChild(const RenderBox&) const;
 
     void layoutFlexItems(bool relayoutChildren, Vector<LineContext>&);
     LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace);
@@ -139,7 +139,8 @@
 
     LayoutUnit computeChildMarginValue(const Length& margin);
     void prepareOrderIteratorAndMargins();
-    LayoutUnit adjustChildSizeForMinAndMax(RenderBox&, LayoutUnit childSize);
+    LayoutUnit adjustChildSizeForMinAndMax(const RenderBox&, LayoutUnit childSize);
+    LayoutUnit adjustChildSizeForAspectRatioCrossAxisMinAndMax(const RenderBox&, LayoutUnit childSize);
     bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent, bool& hasInfiniteLineLength);
 
     bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit>& childSizes, bool hasInfiniteLineLength);
@@ -158,9 +159,11 @@
     void flipForRightToLeftColumn();
     void flipForWrapReverse(const Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
 
-    bool mainAxisExtentIsDefinite() const;
-    bool mainAxisLengthIsIndefinite(const Length& flexBasis) const;
-
+    bool mainAxisLengthIsDefinite(const RenderBox&, const Length&) const;
+    bool crossAxisLengthIsDefinite(const RenderBox&, const Length&) const;
+    bool useChildAspectRatio(const RenderBox&) const;
+    Optional<LayoutUnit> computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const;
+    
     virtual bool isFlexibleBoxImpl() const { return false; };
 
     mutable OrderIterator m_orderIterator;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to