From e522b2dee4630e79b11b3209e11dd9fba85fcb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Sj=C3=B6lander?= Date: Mon, 10 Dec 2018 09:20:32 -0800 Subject: [PATCH] Fix aspect ratio when stretching with main axis margin (#834) Summary: I've noticed that when a child's size is determined by `align-items: stretch` in combination with `aspect-ratio` its size is wrongly calculated to account for margin in the main axis when there is more than enough space. See playground: https://goo.gl/tgW6cD I've yet to figure out exactly how to solve this but i've started by writing a failing test when can be seen in the first commit here. I assumed I had found the bug here https://github.com/facebook/yoga/blob/master/yoga/Yoga.cpp#L1838 where margin is being subtracted from the desired width even though the measure mode tells it to measure to exactly that size. However, if we don't remove this margin from the available width then 15 tests fail (including the one I just added) not quite figured out why yet. I'm also a bit confused at to why this would only happen for nodes with `aspect-ratio` and not for nodes where an explicit height and width is set. Pull Request resolved: https://github.com/facebook/yoga/pull/834 Reviewed By: astreet Differential Revision: D13223579 Pulled By: davidaurelio fbshipit-source-id: 6970e6072e79f3bb6f9097355ab6e441441bfd88 --- tests/YGAspectRatioTest.cpp | 23 +++++++++++++++++++++++ yoga/Yoga.cpp | 10 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 9d99569b5f..c3e5154fdb 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -895,3 +895,26 @@ TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) { YGNodeFreeRecursive(root); } + +TEST( + YogaTest, + aspect_ratio_defined_by_cross_stretch_should_not_be_effected_by_margin_on_main_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 6abfb7d31a..6bc264a1a9 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1382,6 +1382,16 @@ static void YGNodeComputeFlexBasisForChild( auto marginColumn = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + if (YGNodeAlignItem(node, child) == YGAlignStretch) { + if (isMainAxisRow && !YGFloatIsUndefined(height)) { + childHeight = height; + childHeightMeasureMode = YGMeasureModeExactly; + } else if (!isMainAxisRow && !YGFloatIsUndefined(width)) { + childWidth = width; + childWidthMeasureMode = YGMeasureModeExactly; + } + } + if (isRowStyleDimDefined) { childWidth = YGUnwrapFloatOptional(YGResolveValue(