Changeset 279286 in webkit


Ignore:
Timestamp:
Jun 25, 2021 8:42:07 AM (13 months ago)
Author:
svillar@igalia.com
Message:

[css-flexbox] Improve computation of intrinsic sizes of flex items with aspect ratio
https://bugs.webkit.org/show_bug.cgi?id=227395

Reviewed by Rob Buis.

Source/WebCore:

Before computing the intrinsic sizes of flex items we first clear the overriding sizes of the item
that might have been set before in order to get the proper intrinsic size. However there is one
situation in which having an overriding size is desirable and it's when the cross size should
be set to the flex container's definite cross size. That's one of the exceptions for definite/indefinite
sizes mentioned in the specs (see https://drafts.csswg.org/css-flexbox/#definite-sizes).

In the aforementioned case we should temporarily set that overriding size in the cross axis so that
the intrinsic size could be computed with that constrain.

  • rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::computeChildIntrinsicLogicalWidths const): Set the overriding size
in the cross axis to compute the intrinsic size.
(WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing const):
(WebCore::RenderFlexibleBox::childCrossSizeShouldUseContainerCrossSize const): Added a missing check,
the cross size of the child must be auto, otherwise the rule does not apply.
(WebCore::RenderFlexibleBox::computeCrossSizeForChildUsingContainerCrossSize const): Refactored from
computeMainSizeFromAspectRatioUsing() as it's now used in two different places.

  • rendering/RenderFlexibleBox.h:

LayoutTests:

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r279284 r279286  
     12021-06-25  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [css-flexbox] Improve computation of intrinsic sizes of flex items with aspect ratio
     4        https://bugs.webkit.org/show_bug.cgi?id=227395
     5
     6        Reviewed by Rob Buis.
     7
     8        * TestExpectations: Unskipped 3 tests that are now passing.
     9
    1102021-06-17  Sergio Villar Senin  <svillar@igalia.com>
    211
  • trunk/LayoutTests/TestExpectations

    r279271 r279286  
    39533953webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-column-015.html [ ImageOnlyFailure ]
    39543954webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/flex-aspect-ratio-img-row-010.html [ ImageOnlyFailure ]
    3955 webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-001.html [ ImageOnlyFailure ]
    39563955webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-002.html [ ImageOnlyFailure ]
    3957 webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-003.html [ ImageOnlyFailure ]
    39583956webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-004.html [ ImageOnlyFailure ]
    39593957webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-005.html [ ImageOnlyFailure ]
    3960 webkit.org/b/219343 imported/w3c/web-platform-tests/css/css-flexbox/aspect-ratio-intrinsic-size-006.html [ ImageOnlyFailure ]
    39613958
    39623959webkit.org/b/145176 imported/w3c/web-platform-tests/css/css-flexbox/flexbox_align-items-stretch-3.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r279285 r279286  
     12021-06-25  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [css-flexbox] Improve computation of intrinsic sizes of flex items with aspect ratio
     4        https://bugs.webkit.org/show_bug.cgi?id=227395
     5
     6        Reviewed by Rob Buis.
     7
     8        Before computing the intrinsic sizes of flex items we first clear the overriding sizes of the item
     9        that might have been set before in order to get the proper intrinsic size. However there is one
     10        situation in which having an overriding size is desirable and it's when the cross size should
     11        be set to the flex container's definite cross size. That's one of the exceptions for definite/indefinite
     12        sizes mentioned in the specs (see https://drafts.csswg.org/css-flexbox/#definite-sizes).
     13
     14        In the aforementioned case we should temporarily set that overriding size in the cross axis so that
     15        the intrinsic size could be computed with that constrain.
     16
     17        * rendering/RenderFlexibleBox.cpp:
     18        (WebCore::RenderFlexibleBox::computeChildIntrinsicLogicalWidths const): Set the overriding size
     19        in the cross axis to compute the intrinsic size.
     20        (WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing const):
     21        (WebCore::RenderFlexibleBox::childCrossSizeShouldUseContainerCrossSize const): Added a missing check,
     22        the cross size of the child must be auto, otherwise the rule does not apply.
     23        (WebCore::RenderFlexibleBox::computeCrossSizeForChildUsingContainerCrossSize const): Refactored from
     24        computeMainSizeFromAspectRatioUsing() as it's now used in two different places.
     25        * rendering/RenderFlexibleBox.h:
     26
    1272021-06-25  Philippe Normand  <pnormand@igalia.com>
    228
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r279274 r279286  
    213213    RenderBox& child = downcast<RenderBox>(childObject);
    214214
     215    // If the item cross size should use the definite container cross size then set the overriding size now so
     216    // the intrinsic sizes are properly computed in the presence of aspect ratios. The only exception is when
     217    // we are both a flex item&container, because our parent might have already set our overriding size.
     218    if (childCrossSizeShouldUseContainerCrossSize(child) && !isFlexItem()) {
     219        auto axis = mainAxisIsChildInlineAxis(child) ? OverridingSizesScope::Axis::Block : OverridingSizesScope::Axis::Inline;
     220        OverridingSizesScope overridingSizeScope(child, axis, computeCrossSizeForChildUsingContainerCrossSize(child));
     221        RenderBlock::computeChildIntrinsicLogicalWidths(childObject, minPreferredLogicalWidth, maxPreferredLogicalWidth);
     222        return;
     223    }
     224
    215225    OverridingSizesScope cleanOverridingSizesScope(child, OverridingSizesScope::Axis::Both);
    216226    RenderBlock::computeChildIntrinsicLogicalWidths(childObject, minPreferredLogicalWidth, maxPreferredLogicalWidth);
     
    870880    if (crossSizeLength.isFixed())
    871881        crossSize = adjustForBoxSizing(child, crossSizeLength);
    872     else if (crossSizeLength.isAuto()) {
    873         ASSERT(childCrossSizeShouldUseContainerCrossSize(child));
    874         auto containerCrossSizeLength = isHorizontalFlow() ? style().height() : style().width();
    875         // Keep this sync'ed with childCrossSizeShouldUseContainerCrossSize().
    876         ASSERT(containerCrossSizeLength.isFixed());
    877         crossSize = std::max(0_lu, valueForLength(containerCrossSizeLength, -1_lu) - crossAxisMarginExtentForChild(child));
    878     } else {
     882    else if (crossSizeLength.isAuto())
     883        crossSize = computeCrossSizeForChildUsingContainerCrossSize(child);
     884    else {
    879885        ASSERT(crossSizeLength.isPercentOrCalculated());
    880886        crossSize = mainAxisIsChildInlineAxis(child) ? child.computePercentageLogicalHeight(crossSizeLength) : adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(crossSizeLength, contentWidth()), crossSizeLength.type());
     
    949955    // stretched flex items is the flex container's inner cross size (clamped to the flex item's min and max cross size)
    950956    // and is considered definite.
    951     if (!isMultiline() && alignmentForChild(child) == ItemPosition::Stretch && !hasAutoMarginsInCrossAxis(child)) {
     957    if (!isMultiline() && alignmentForChild(child) == ItemPosition::Stretch && !hasAutoMarginsInCrossAxis(child) && crossSizeLengthForChild(MainOrPreferredSize, child).isAuto()) {
    952958        // This must be kept in sync with computeMainSizeFromAspectRatioUsing().
    953959        // FIXME: so far we're only considered fixed sizes but we should extend it to other definite sizes.
     
    16681674}
    16691675
     1676// This refers to https://drafts.csswg.org/css-flexbox-1/#definite-sizes, section 1).
     1677LayoutUnit RenderFlexibleBox::computeCrossSizeForChildUsingContainerCrossSize(const RenderBox& child) const
     1678{
     1679    auto containerCrossSizeLength = isHorizontalFlow() ? style().height() : style().width();
     1680    // Keep this sync'ed with childCrossSizeShouldUseContainerCrossSize().
     1681    ASSERT(containerCrossSizeLength.isFixed());
     1682    return std::max(0_lu, valueForLength(containerCrossSizeLength, -1_lu) - crossAxisMarginExtentForChild(child));
     1683}
     1684
    16701685void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox& child)
    16711686{
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.h

    r279274 r279286  
    146146    bool childHasComputableAspectRatioAndCrossSizeIsConsideredDefinite(const RenderBox&);
    147147    bool childCrossSizeShouldUseContainerCrossSize(const RenderBox& child) const;
     148    LayoutUnit computeCrossSizeForChildUsingContainerCrossSize(const RenderBox& child) const;
    148149    void computeChildIntrinsicLogicalWidths(RenderObject&, LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
    149150    LayoutUnit computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const;
Note: See TracChangeset for help on using the changeset viewer.