From: David Steele Date: Tue, 29 May 2018 18:00:04 +0000 (+0100) Subject: Merge branch 'devel/master' into devel/vulkan X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ae4a08c1b868390ca1ca8bb162a34ce20b4dfea;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Merge branch 'devel/master' into devel/vulkan Change-Id: Ib5ef23939686246c268f9b5c13d0dbc99374c811 --- 6ae4a08c1b868390ca1ca8bb162a34ce20b4dfea diff --cc automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h index 0000000,23334ba..80defc1 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h +++ b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h @@@ -1,0 -1,97 +1,97 @@@ + #ifndef __DALI_TOOLKIT_TEST_DUMMY_VISUAL_H__ + #define __DALI_TOOLKIT_TEST_DUMMY_VISUAL_H__ + + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + // INTERNAL INCLUDES + #include + #include + #include + + #include + + // EXTERNAL INCLUDES + #include + + namespace Dali + { + + namespace Toolkit + { + + namespace Internal + { + + class DummyVisual; + + typedef IntrusivePtr< DummyVisual > DummyVisualPtr; + + /** + * Dummy Visual that can be used for testing + * Cannot create an instance of an existing Visual, so use this dummy class for the implementation. + */ + class DummyVisual : public Visual::Base + { + public: + + // Actions that the dummy visual can perform. These actions are called through the Visual::Base::DoAction API. + enum Type + { + TEST_ACTION = 0, ///< Updates the action counter + }; + + public: + + // Constructor for DummyVisual + static DummyVisualPtr New( const Property::Map& properties ); + + // Prevent default methods being used. + DummyVisual( const DummyVisual& dummyVisual ) = delete; + DummyVisual( const DummyVisual&& dummyVisual ) = delete; + DummyVisual& operator=( const DummyVisual& dummyVisual ) = delete; + DummyVisual& operator=( const DummyVisual&& dummyVisual ) = delete; + + // Get the Action counter, action counter incremented with every successful Action + unsigned int GetActionCounter() const; + // Reset the Action counter to 0; + void ResetActionCounter(); + + protected: + + DummyVisual( VisualFactoryCache& factoryCache ); + + virtual void DoCreatePropertyMap( Property::Map& map ) const override; + virtual void DoCreateInstancePropertyMap( Property::Map& map ) const override; + virtual void DoSetProperties( const Property::Map& propertyMap ) override; + virtual void OnSetTransform() override; + virtual void DoSetOnStage( Actor& actor ) override; + virtual void OnDoAction( const Property::Index actionName, const Property::Value& attributes ) override; + + private: + unsigned int mActionCounter; + + }; + + + } // Internal + + } // namespace Toolkit + + } // namespace Dali + + #endif // __DALI_TOOLKIT_TEST_DUMMY_VISUAL_H__ diff --cc automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp index 8d73622,c87af41..ff4cf14 mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp index f6c58db,86edead..ffc851f --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp index 50ca75d,44136a7..5e34fb8 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp index 13595ab,49d36e0..7bf2702 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp index c2161d1,af5f1a6..640c81c --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-styling/utc-Dali-StyleManager.cpp index 07d657f,591ec8f..744d4ca mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit-styling/utc-Dali-StyleManager.cpp +++ b/automated-tests/src/dali-toolkit-styling/utc-Dali-StyleManager.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAbsolutePositionTest.cpp index 0000000,a319cf1..a78d2f5 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAbsolutePositionTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAbsolutePositionTest.cpp @@@ -1,0 -1,1031 +1,1031 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAbsolutePositionTest.html + + #include + #include + + TEST(YogaTest, absolute_layout_width_height_start_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_width_height_end_bottom) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeEnd, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_start_top_end_bottom) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeEnd, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_width_height_start_top_end_bottom) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeEnd, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetOverflow(root, YGOverflowHidden); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeStart, 0); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_within_border) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root, YGEdgeTop, 10); + YGNodeStyleSetMargin(root, YGEdgeRight, 10); + YGNodeStyleSetMargin(root, YGEdgeBottom, 10); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child1, YGEdgeRight, 0); + YGNodeStyleSetPosition(root_child1, YGEdgeBottom, 0); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child2, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child2, YGEdgeLeft, 0); + YGNodeStyleSetPosition(root_child2, YGEdgeTop, 0); + YGNodeStyleSetMargin(root_child2, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child2, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child2, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child2, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child3, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child3, YGEdgeRight, 0); + YGNodeStyleSetPosition(root_child3, YGEdgeBottom, 0); + YGNodeStyleSetMargin(root_child3, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_justify_content_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_center_on_child_only) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignCenter); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_top_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_bottom_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_left_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_right_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 110); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 5); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, position_root_with_rtl_should_position_withoutdirection) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root, YGEdgeLeft, 72); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_percentage_bottom_based_on_parent_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child1, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child2, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child2, YGEdgeTop, 10); + YGNodeStyleSetPositionPercent(root_child2, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAlignContentTest.cpp index 0000000,7cd5c09..bb8adf7 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignContentTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignContentTest.cpp @@@ -1,0 -1,1878 +1,1878 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignContentTest.html + + #include + #include + + TEST(YogaTest, align_content_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 130); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeStyleSetHeight(root_child4, 10); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_flex_start_without_height_on_children) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_flex_start_with_flex) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 120); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetFlexShrink(root_child3, 1); + YGNodeStyleSetFlexBasisPercent(root_child3, 0); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeStyleSetHeight(root_child4, 10); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_spacebetween) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceBetween); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 130); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeStyleSetHeight(root_child4, 10); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_spacearound) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeStyleSetHeight(root_child4, 10); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(95, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(95, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_children) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_flex) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetFlexShrink(root_child3, 1); + YGNodeStyleSetFlexBasisPercent(root_child3, 0); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_flex_no_shrink) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetFlexBasisPercent(root_child3, 0); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child3, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child3, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child1, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child1, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child1, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child1, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child3, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child3, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child3, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child3, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_single_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_fixed_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 60); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMaxHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_row_with_min_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMinHeight(root_child1, 80); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 150); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_content_stretch_is_not_overriding_align_items) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0, YGAlignStretch); + YGNodeStyleSetAlignItems(root_child0, YGAlignCenter); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAlignItemsTest.cpp index 0000000,fd5e424..4740342 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignItemsTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignItemsTest.cpp @@@ -1,0 -1,2158 +1,2158 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignItemsTest.html + + #include + #include + + TEST(YogaTest, align_items_stretch) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_multiline) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_multiline_override) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child1_child1, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_multiline_no_override_on_secondline) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_top2) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root_child1, YGEdgeTop, 5); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_double_nested_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 15); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeLeft, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-1, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_child_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_multiline) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2_child0, 50); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_multiline_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 20); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + YGNodeStyleSetHeight(root_child2, 70); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2_child0, 10); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_multiline_column2) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 20); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + YGNodeStyleSetHeight(root_child2, 70); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2_child0, 10); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_baseline_multiline_row_and_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2_child0, 50); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_center_child_with_margin_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignCenter); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 52); + YGNodeStyleSetHeight(root_child0_child0, 52); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_flex_end_child_with_margin_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexEnd); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 52); + YGNodeStyleSetHeight(root_child0_child0, 52); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_center_child_without_margin_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignCenter); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 72); + YGNodeStyleSetHeight(root_child0_child0, 72); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_flex_end_child_without_margin_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexEnd); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 72); + YGNodeStyleSetHeight(root_child0_child0, 72); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_center_should_size_based_on_content) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 20); + YGNodeStyleSetHeight(root_child0_child0_child0, 20); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_strech_should_size_based_on_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 20); + YGNodeStyleSetHeight(root_child0_child0_child0, 20); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_flex_start_with_shrinking_children) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_flex_start_with_stretching_children) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_flex_start_with_shrinking_children_with_stretch) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAlignSelfTest.cpp index 0000000,00bb7b9..9adf8d8 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignSelfTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAlignSelfTest.cpp @@@ -1,0 -1,249 +1,249 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignSelfTest.html + + #include + #include + + TEST(YogaTest, align_self_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignCenter); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_self_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_self_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_self_flex_end_override_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_self_baseline) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignBaseline); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child1, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAndroidNewsFeed.cpp index 0000000,fb3f073..413d3b1 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAndroidNewsFeed.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAndroidNewsFeed.cpp @@@ -1,0 -1,445 +1,445 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAndroidNewsFeed.html + + #include + #include + + TEST(YogaTest, android_news_feed) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetWidth(root, 1080); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0_child0_child0_child0, YGAlignStretch); + YGNodeStyleSetAlignItems(root_child0_child0_child0_child0, YGAlignFlexStart); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeStart, 36); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 24); + YGNodeInsertChild( + root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0_child0_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child0_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent( + root_child0_child0_child0_child0_child0, YGAlignStretch); + YGNodeInsertChild( + root_child0_child0_child0_child0, + root_child0_child0_child0_child0_child0, + 0); + + const YGNodeRef root_child0_child0_child0_child0_child0_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child0_child0_child0_child0, YGAlignStretch); + YGNodeStyleSetWidth(root_child0_child0_child0_child0_child0_child0, 120); + YGNodeStyleSetHeight(root_child0_child0_child0_child0_child0_child0, 120); + YGNodeInsertChild( + root_child0_child0_child0_child0_child0, + root_child0_child0_child0_child0_child0_child0, + 0); + + const YGNodeRef root_child0_child0_child0_child0_child1 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child0_child0_child1, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child0_child0_child1, 1); + YGNodeStyleSetMargin( + root_child0_child0_child0_child0_child1, YGEdgeRight, 36); + YGNodeStyleSetPadding( + root_child0_child0_child0_child0_child1, YGEdgeLeft, 36); + YGNodeStyleSetPadding(root_child0_child0_child0_child0_child1, YGEdgeTop, 21); + YGNodeStyleSetPadding( + root_child0_child0_child0_child0_child1, YGEdgeRight, 36); + YGNodeStyleSetPadding( + root_child0_child0_child0_child0_child1, YGEdgeBottom, 18); + YGNodeInsertChild( + root_child0_child0_child0_child0, + root_child0_child0_child0_child0_child1, + 1); + + const YGNodeRef root_child0_child0_child0_child0_child1_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child0_child0_child1_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent( + root_child0_child0_child0_child0_child1_child0, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child0_child0_child1_child0, 1); + YGNodeInsertChild( + root_child0_child0_child0_child0_child1, + root_child0_child0_child0_child0_child1_child0, + 0); + + const YGNodeRef root_child0_child0_child0_child0_child1_child1 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child0_child0_child1_child1, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child0_child0_child1_child1, 1); + YGNodeInsertChild( + root_child0_child0_child0_child0_child1, + root_child0_child0_child0_child0_child1_child1, + 1); + + const YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0_child1, YGAlignStretch); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + const YGNodeRef root_child0_child0_child1_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child1_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0_child0_child1_child0, YGAlignStretch); + YGNodeStyleSetAlignItems(root_child0_child0_child1_child0, YGAlignFlexStart); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeStart, 174); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 24); + YGNodeInsertChild( + root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + const YGNodeRef root_child0_child0_child1_child0_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child1_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent( + root_child0_child0_child1_child0_child0, YGAlignStretch); + YGNodeInsertChild( + root_child0_child0_child1_child0, + root_child0_child0_child1_child0_child0, + 0); + + const YGNodeRef root_child0_child0_child1_child0_child0_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child1_child0_child0_child0, YGAlignStretch); + YGNodeStyleSetWidth(root_child0_child0_child1_child0_child0_child0, 72); + YGNodeStyleSetHeight(root_child0_child0_child1_child0_child0_child0, 72); + YGNodeInsertChild( + root_child0_child0_child1_child0_child0, + root_child0_child0_child1_child0_child0_child0, + 0); + + const YGNodeRef root_child0_child0_child1_child0_child1 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child1_child0_child1, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child1_child0_child1, 1); + YGNodeStyleSetMargin( + root_child0_child0_child1_child0_child1, YGEdgeRight, 36); + YGNodeStyleSetPadding( + root_child0_child0_child1_child0_child1, YGEdgeLeft, 36); + YGNodeStyleSetPadding(root_child0_child0_child1_child0_child1, YGEdgeTop, 21); + YGNodeStyleSetPadding( + root_child0_child0_child1_child0_child1, YGEdgeRight, 36); + YGNodeStyleSetPadding( + root_child0_child0_child1_child0_child1, YGEdgeBottom, 18); + YGNodeInsertChild( + root_child0_child0_child1_child0, + root_child0_child0_child1_child0_child1, + 1); + + const YGNodeRef root_child0_child0_child1_child0_child1_child0 = + YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection( + root_child0_child0_child1_child0_child1_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent( + root_child0_child0_child1_child0_child1_child0, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child1_child0_child1_child0, 1); + YGNodeInsertChild( + root_child0_child0_child1_child0_child1, + root_child0_child0_child1_child0_child1_child0, + 0); + + const YGNodeRef root_child0_child0_child1_child0_child1_child1 = + YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent( + root_child0_child0_child1_child0_child1_child1, YGAlignStretch); + YGNodeStyleSetFlexShrink(root_child0_child0_child1_child0_child1_child1, 1); + YGNodeInsertChild( + root_child0_child0_child1_child0_child1, + root_child0_child0_child1_child0_child1_child1, + 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(144, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(1044, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, + YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, + YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 120, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 39, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(144, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(96, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(174, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(906, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 72, + YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 39, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(144, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(1044, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 924, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, + YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 120, + YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 816, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1)); + ASSERT_FLOAT_EQ( + 39, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(144, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(96, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(906, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 834, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child0)); + + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child0_child0)); + ASSERT_FLOAT_EQ( + 72, + YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child0_child0)); + + ASSERT_FLOAT_EQ( + 726, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 72, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1)); + ASSERT_FLOAT_EQ( + 39, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1_child0)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1_child0)); + + ASSERT_FLOAT_EQ( + 36, YGNodeLayoutGetLeft(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 21, YGNodeLayoutGetTop(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetWidth(root_child0_child0_child1_child0_child1_child1)); + ASSERT_FLOAT_EQ( + 0, YGNodeLayoutGetHeight(root_child0_child0_child1_child0_child1_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGAspectRatioTest.cpp index 0000000,c49133e..73160ac mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGAspectRatioTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGAspectRatioTest.cpp @@@ -1,0 -1,898 +1,898 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + static YGSize _measure_for_aspect_ratio(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + return YGSize{ + .width = widthMode == YGMeasureModeExactly ? width : 50, + .height = heightMode == YGMeasureModeExactly ? height : 50, + }; + } + + TEST(YogaTest, aspect_ratio_cross_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_main_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_align_stretch) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_flex_grow) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_flex_shrink) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 150); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_flex_shrink_2) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeightPercent(root_child0, 100); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetHeightPercent(root_child1, 100); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetAspectRatio(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_basis) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_absolute_layout_width_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_absolute_layout_height_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_with_max_cross_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetMaxWidth(root_child0, 40); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_with_max_main_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetMaxHeight(root_child0, 40); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_with_min_cross_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 30); + YGNodeStyleSetMinWidth(root_child0, 40); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_with_min_main_defined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetMinHeight(root_child0, 40); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_double_cross) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 2); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_half_cross) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetAspectRatio(root_child0, 0.5); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_double_main) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 0.5); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_half_main) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetAspectRatio(root_child0, 2); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_with_measure_func) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setMeasureFunc(_measure_for_aspect_ratio); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_width_height_flex_grow_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_height_as_flex_basis) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetAspectRatio(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_width_as_flex_basis) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetAspectRatio(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 0.5); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 2); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_left_right_absolute) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 10); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_top_bottom_absolute) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_width_overrides_align_stretch_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_height_overrides_align_stretch_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_allow_child_overflow_parent_size) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 4); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_defined_main_with_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_defined_cross_with_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_defined_cross_with_main_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_should_prefer_explicit_height) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumn); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeStyleSetAspectRatio(root_child0_child0, 2); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, 100, 200, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_should_prefer_explicit_width) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetAspectRatio(root_child0_child0, 0.5); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, 200, 100, YGDirectionLTR); + + ASSERT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn); + YGNodeStyleSetAspectRatio(root_child0, 2); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAspectRatio(root_child0_child0, 4); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGBaselineFuncTest.cpp index 0000000,c8d1ff1..4cd7b67 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGBaselineFuncTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGBaselineFuncTest.cpp @@@ -1,0 -1,62 +1,62 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + static float _baseline(YGNodeRef node, const float width, const float height) { + float* baseline = (float*)node->getContext(); + return *baseline; + } + + TEST(YogaTest, align_baseline_customer_func) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + float baselineValue = 10; + const YGNodeRef root_child1_child0 = YGNodeNew(); + root_child1_child0->setContext(&baselineValue); + YGNodeStyleSetWidth(root_child1_child0, 50); + root_child1_child0->setBaseLineFunc(_baseline); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGBorderTest.cpp index 0000000,d4e6376..a37a1b8 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGBorderTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGBorderTest.cpp @@@ -1,0 -1,212 +1,212 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGBorderTest.html + + #include + #include + + TEST(YogaTest, border_no_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, border_container_match_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, border_flex_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, border_stretch_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, border_center_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetBorder(root, YGEdgeStart, 10); + YGNodeStyleSetBorder(root, YGEdgeEnd, 20); + YGNodeStyleSetBorder(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGComputedMarginTest.cpp index 0000000,9cbbe4e..2f4f1dd mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGComputedMarginTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGComputedMarginTest.cpp @@@ -1,0 -1,28 +1,28 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, computed_layout_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetMarginPercent(root, YGEdgeStart, 10); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeRight)); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(root, YGEdgeRight)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGComputedPaddingTest.cpp index 0000000,bf31fe7..1b1eb01 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGComputedPaddingTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGComputedPaddingTest.cpp @@@ -1,0 -1,28 +1,28 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, computed_layout_padding) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetPaddingPercent(root, YGEdgeStart, 10); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetPadding(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeRight)); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetPadding(root, YGEdgeRight)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGDefaultValuesTest.cpp index 0000000,ca14386..9dc73bf mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGDefaultValuesTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGDefaultValuesTest.cpp @@@ -1,0 -1,164 +1,164 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, assert_default_values) { + const YGNodeRef root = YGNodeNew(); + + ASSERT_EQ(0, YGNodeGetChildCount(root)); + ASSERT_EQ(NULL, YGNodeGetChild(root, 1)); + + ASSERT_EQ(YGDirectionInherit, YGNodeStyleGetDirection(root)); + ASSERT_EQ(YGFlexDirectionColumn, YGNodeStyleGetFlexDirection(root)); + ASSERT_EQ(YGJustifyFlexStart, YGNodeStyleGetJustifyContent(root)); + ASSERT_EQ(YGAlignFlexStart, YGNodeStyleGetAlignContent(root)); + ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignItems(root)); + ASSERT_EQ(YGAlignAuto, YGNodeStyleGetAlignSelf(root)); + ASSERT_EQ(YGPositionTypeRelative, YGNodeStyleGetPositionType(root)); + ASSERT_EQ(YGWrapNoWrap, YGNodeStyleGetFlexWrap(root)); + ASSERT_EQ(YGOverflowVisible, YGNodeStyleGetOverflow(root)); + ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexGrow(root)); + ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexShrink(root)); + ASSERT_EQ(YGNodeStyleGetFlexBasis(root).unit, YGUnitAuto); + + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeLeft).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeTop).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeRight).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeBottom).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeStart).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeEnd).unit, YGUnitUndefined); + + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeLeft).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeTop).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeRight).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeBottom).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeStart).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMargin(root, YGEdgeEnd).unit, YGUnitUndefined); + + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeLeft).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeTop).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeRight).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeBottom).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeStart).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetPadding(root, YGEdgeEnd).unit, YGUnitUndefined); + + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeLeft))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeTop))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeRight))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeBottom))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeStart))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeEnd))); + + ASSERT_EQ(YGNodeStyleGetWidth(root).unit, YGUnitAuto); + ASSERT_EQ(YGNodeStyleGetHeight(root).unit, YGUnitAuto); + ASSERT_EQ(YGNodeStyleGetMinWidth(root).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMinHeight(root).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMaxWidth(root).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetMaxHeight(root).unit, YGUnitUndefined); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetRight(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetBottom(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeTop)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeRight)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeBottom)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeTop)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeRight)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(root, YGEdgeBottom)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetBorder(root, YGEdgeLeft)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetBorder(root, YGEdgeTop)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetBorder(root, YGEdgeRight)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetBorder(root, YGEdgeBottom)); + + ASSERT_TRUE(YGFloatIsUndefined(YGNodeLayoutGetWidth(root))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeLayoutGetHeight(root))); + ASSERT_EQ(YGDirectionInherit, YGNodeLayoutGetDirection(root)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, assert_webdefault_values) { + YGConfig *config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + const YGNodeRef root = YGNodeNewWithConfig(config); + + ASSERT_EQ(YGFlexDirectionRow, YGNodeStyleGetFlexDirection(root)); + ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignContent(root)); + ASSERT_FLOAT_EQ(1.0f, YGNodeStyleGetFlexShrink(root)); + + YGNodeFreeRecursive(root); + YGConfigFree(config); + } + + TEST(YogaTest, assert_webdefault_values_reset) { + YGConfig *config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeReset(root); + + ASSERT_EQ(YGFlexDirectionRow, YGNodeStyleGetFlexDirection(root)); + ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignContent(root)); + ASSERT_FLOAT_EQ(1.0f, YGNodeStyleGetFlexShrink(root)); + + YGNodeFreeRecursive(root); + YGConfigFree(config); + } + + TEST(YogaTest, assert_legacy_stretch_behaviour) { + YGConfig *config = YGConfigNew(); + YGConfigSetUseLegacyStretchBehaviour(config, true); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGDimensionTest.cpp index 0000000,42fc123..92945de mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGDimensionTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGDimensionTest.cpp @@@ -1,0 -1,100 +1,100 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDimensionTest.html + + #include + #include + + TEST(YogaTest, wrap_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_grandchild) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGDirtiedTest.cpp index 0000000,bb0c05d..e2e7a10 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGDirtiedTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGDirtiedTest.cpp @@@ -1,0 -1,107 +1,107 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + static void _dirtied(YGNodeRef node) { + int* dirtiedCount = (int*)node->getContext(); + (*dirtiedCount)++; + } + + TEST(YogaTest, dirtied) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + int dirtiedCount = 0; + root->setContext(&dirtiedCount); + root->setDirtiedFunc(_dirtied); + + ASSERT_EQ(0, dirtiedCount); + + // `_dirtied` MUST be called in case of explicit dirtying. + root->setDirty(true); + ASSERT_EQ(1, dirtiedCount); + + // `_dirtied` MUST be called ONCE. + root->setDirty(true); + ASSERT_EQ(1, dirtiedCount); + } + + TEST(YogaTest, dirtied_propagation) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + int dirtiedCount = 0; + root->setContext(&dirtiedCount); + root->setDirtiedFunc(_dirtied); + + ASSERT_EQ(0, dirtiedCount); + + // `_dirtied` MUST be called for the first time. + root_child0->markDirtyAndPropogate(); + ASSERT_EQ(1, dirtiedCount); + + // `_dirtied` must NOT be called for the second time. + root_child0->markDirtyAndPropogate(); + ASSERT_EQ(1, dirtiedCount); + } + + TEST(YogaTest, dirtied_hierarchy) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + int dirtiedCount = 0; + root_child0->setContext(&dirtiedCount); + root_child0->setDirtiedFunc(_dirtied); + + ASSERT_EQ(0, dirtiedCount); + + // `_dirtied` must NOT be called for descendants. + root->markDirtyAndPropogate(); + ASSERT_EQ(0, dirtiedCount); + + // `_dirtied` must NOT be called for the sibling node. + root_child1->markDirtyAndPropogate(); + ASSERT_EQ(0, dirtiedCount); + + // `_dirtied` MUST be called in case of explicit dirtying. + root_child0->markDirtyAndPropogate(); + ASSERT_EQ(1, dirtiedCount); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGDirtyMarkingTest.cpp index 0000000,d951f53..dac4758 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGDirtyMarkingTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGDirtyMarkingTest.cpp @@@ -1,0 -1,159 +1,159 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, dirty_propagation) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeStyleSetWidth(root_child0, 20); + + EXPECT_TRUE(root_child0->isDirty()); + EXPECT_FALSE(root_child1->isDirty()); + EXPECT_TRUE(root->isDirty()); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_FALSE(root_child0->isDirty()); + EXPECT_FALSE(root_child1->isDirty()); + EXPECT_FALSE(root->isDirty()); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dirty_propagation_only_if_prop_changed) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeStyleSetWidth(root_child0, 50); + + EXPECT_FALSE(root_child0->isDirty()); + EXPECT_FALSE(root_child1->isDirty()); + EXPECT_FALSE(root->isDirty()); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dirty_mark_all_children_as_dirty_when_display_changes) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(child0, 1); + const YGNodeRef child1 = YGNodeNew(); + YGNodeStyleSetFlexGrow(child1, 1); + + const YGNodeRef child1_child0 = YGNodeNew(); + const YGNodeRef child1_child0_child0 = YGNodeNew(); + YGNodeStyleSetWidth(child1_child0_child0, 8); + YGNodeStyleSetHeight(child1_child0_child0, 16); + + YGNodeInsertChild(child1_child0, child1_child0_child0, 0); + + YGNodeInsertChild(child1, child1_child0, 0); + YGNodeInsertChild(root, child0, 0); + YGNodeInsertChild(root, child1, 0); + + YGNodeStyleSetDisplay(child0, YGDisplayFlex); + YGNodeStyleSetDisplay(child1, YGDisplayNone); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(child1_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(child1_child0_child0)); + + YGNodeStyleSetDisplay(child0, YGDisplayNone); + YGNodeStyleSetDisplay(child1, YGDisplayFlex); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetWidth(child1_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(child1_child0_child0)); + + YGNodeStyleSetDisplay(child0, YGDisplayFlex); + YGNodeStyleSetDisplay(child1, YGDisplayNone); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(child1_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(child1_child0_child0)); + + YGNodeStyleSetDisplay(child0, YGDisplayNone); + YGNodeStyleSetDisplay(child1, YGDisplayFlex); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetWidth(child1_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(child1_child0_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dirty_node_only_if_children_are_actually_removed) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef child0 = YGNodeNew(); + YGNodeStyleSetWidth(child0, 50); + YGNodeStyleSetHeight(child0, 25); + YGNodeInsertChild(root, child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + const YGNodeRef child1 = YGNodeNew(); + YGNodeRemoveChild(root, child1); + EXPECT_FALSE(root->isDirty()); + YGNodeFree(child1); + + YGNodeRemoveChild(root, child0); + EXPECT_TRUE(root->isDirty()); + YGNodeFree(child0); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dirty_node_only_if_undefined_values_gets_set_to_undefined) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + YGNodeStyleSetMinWidth(root, YGUndefined); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_FALSE(root->isDirty()); + + YGNodeStyleSetMinWidth(root, YGUndefined); + + EXPECT_FALSE(root->isDirty()); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGDisplayTest.cpp index 0000000,45256ac..56b63d0 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGDisplayTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGDisplayTest.cpp @@@ -1,0 -1,332 +1,332 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html + + #include + #include + + TEST(YogaTest, display_none) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetDisplay(root_child1, YGDisplayNone); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, display_none_fixed_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeStyleSetDisplay(root_child1, YGDisplayNone); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, display_none_with_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeStyleSetDisplay(root_child0, YGDisplayNone); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, display_none_with_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetDisplay(root_child1, YGDisplayNone); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child0, 1); + YGNodeStyleSetFlexShrink(root_child1_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child1_child0, 0); + YGNodeStyleSetWidth(root_child1_child0, 20); + YGNodeStyleSetMinWidth(root_child1_child0, 0); + YGNodeStyleSetMinHeight(root_child1_child0, 0); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetFlexShrink(root_child2, 1); + YGNodeStyleSetFlexBasisPercent(root_child2, 0); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, display_none_with_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetPosition(root_child1, YGEdgeTop, 10); + YGNodeStyleSetDisplay(root_child1, YGDisplayNone); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGEdgeTest.cpp index 0000000,02de146..749cbf8 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGEdgeTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGEdgeTest.cpp @@@ -1,0 -1,161 +1,161 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, start_overrides) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetRight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetRight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, end_overrides) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetRight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetRight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, horizontal_overridden) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeHorizontal, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetRight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, vertical_overridden) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeVertical, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetBottom(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, horizontal_overrides_all) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeHorizontal, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeAll, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetRight(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetBottom(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, vertical_overrides_all) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeVertical, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeAll, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetRight(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetBottom(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, all_overridden) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeAll, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetRight(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetBottom(root_child0)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGFlexDirectionTest.cpp index 0000000,93e0942..b483d2e mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexDirectionTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexDirectionTest.cpp @@@ -1,0 -1,415 +1,415 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexDirectionTest.html + + #include + #include + + TEST(YogaTest, flex_direction_column_no_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_direction_row_no_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_direction_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_direction_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_direction_column_reverse) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_direction_row_reverse) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGFlexTest.cpp index 0000000,e1a8ba8..0728578 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexTest.cpp @@@ -1,0 -1,491 +1,491 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexTest.html + + #include + #include + + TEST(YogaTest, flex_basis_flex_grow_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_basis_flex_grow_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_basis_flex_shrink_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_basis_flex_shrink_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_shrink_to_zero) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root, 75); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_basis_overrides_main_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_shrink_at_most) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_less_than_factor_one) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 0.2f); + YGNodeStyleSetFlexBasis(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 0.2f); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 0.4f); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(132, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(132, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(224, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(184, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(132, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(132, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(224, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(184, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGFlexWrapTest.cpp index 0000000,e8e5458..2fa080e mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexWrapTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGFlexWrapTest.cpp @@@ -1,0 -1,1735 +1,1735 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexWrapTest.html + + #include + #include + + TEST(YogaTest, wrap_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 30); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 30); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 30); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 30); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 30); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 30); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_row_align_items_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 30); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_row_align_items_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 30); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_wrap_children_with_min_main_overriding_flex_basis) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetMinWidth(root_child0, 55); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1, 50); + YGNodeStyleSetMinWidth(root_child1, 55); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_wrap_wrap_to_child_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_wrap_align_stretch_fits_one_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_row_align_content_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_row_align_content_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_row_single_line_different_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(270, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(240, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(210, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_row_align_content_stretch) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_row_align_content_space_around) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_reverse_column_fixed_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 30); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + YGNodeStyleSetHeight(root_child2, 30); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 30); + YGNodeStyleSetHeight(root_child3, 40); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 30); + YGNodeStyleSetHeight(root_child4, 50); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrapped_row_within_align_items_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 150); + YGNodeStyleSetHeight(root_child0_child0, 80); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 80); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrapped_row_within_align_items_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 150); + YGNodeStyleSetHeight(root_child0_child0, 80); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 80); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrapped_row_within_align_items_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 150); + YGNodeStyleSetHeight(root_child0_child0, 80); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 80); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrapped_column_max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 700); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeStyleSetMaxHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeRight, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root_child1, 200); + YGNodeStyleSetHeight(root_child1, 200); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(420, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(350, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrapped_column_max_height_flex) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 700); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeStyleSetMaxHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeRight, 20); + YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root_child1, 200); + YGNodeStyleSetHeight(root_child1, 200); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_nodes_with_content_sizing_overflowing_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 85); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 40); + YGNodeStyleSetHeight(root_child0_child0_child0, 40); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child1, YGEdgeRight, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + const YGNodeRef root_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1_child0, 40); + YGNodeStyleSetHeight(root_child0_child1_child0, 40); + YGNodeInsertChild(root_child0_child1, root_child0_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(85, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(415, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(85, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, wrap_nodes_with_content_sizing_margin_cross) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 70); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 40); + YGNodeStyleSetHeight(root_child0_child0_child0, 40); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child1, YGEdgeTop, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + const YGNodeRef root_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1_child0, 40); + YGNodeStyleSetHeight(root_child0_child1_child0, 40); + YGNodeInsertChild(root_child0_child1, root_child0_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(430, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGInfiniteHeightTest.cpp index 0000000,a557b3d..c64405f mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGInfiniteHeightTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGInfiniteHeightTest.cpp @@@ -1,0 -1,53 +1,53 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + // This test isn't correct from the Flexbox standard standpoint, + // because percentages are calculated with parent constraints. + // However, we need to make sure we fail gracefully in this case, not returning NaN + TEST(YogaTest, percent_absolute_position_infinite_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 300); + YGNodeStyleSetHeight(root_child0, 300); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child1, YGEdgeLeft, 20); + YGNodeStyleSetPositionPercent(root_child1, YGEdgeTop, 20); + YGNodeStyleSetWidthPercent(root_child1, 20); + YGNodeStyleSetHeightPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGJustifyContentTest.cpp index 0000000,e5d4216..9a0b458 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGJustifyContentTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGJustifyContentTest.cpp @@@ -1,0 -1,999 +1,999 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGJustifyContentTest.html + + #include + #include + + TEST(YogaTest, justify_content_row_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(82, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(82, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_space_between) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_space_around) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(82, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(82, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_space_between) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_space_around) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_min_width_and_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetMargin(root, YGEdgeLeft, 100); + YGNodeStyleSetMinWidth(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_max_width_and_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetMargin(root, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMaxWidth(root, 80); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_min_height_and_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetMargin(root, YGEdgeTop, 100); + YGNodeStyleSetMinHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_colunn_max_height_and_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetMargin(root, YGEdgeTop, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 80); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_column_space_evenly) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(74, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(74, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_row_space_evenly) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(26, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(51, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(77, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(77, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(51, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(26, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGLayoutDiffingTest.cpp index 0000000,a04e87d..9374b18 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGLayoutDiffingTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGLayoutDiffingTest.cpp @@@ -1,0 -1,87 +1,87 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + TEST(YogaTest, assert_layout_trees_are_same) { + YGConfig* config = YGConfigNew(); + YGConfigSetUseLegacyStretchBehaviour(config, true); + const YGNodeRef root1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root1, 500); + YGNodeStyleSetHeight(root1, 500); + + const YGNodeRef root1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root1_child0, YGAlignFlexStart); + YGNodeInsertChild(root1, root1_child0, 0); + + const YGNodeRef root1_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root1_child0_child0, 1); + YGNodeStyleSetFlexShrink(root1_child0_child0, 1); + YGNodeInsertChild(root1_child0, root1_child0_child0, 0); + + const YGNodeRef root1_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root1_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root1_child0_child0_child0, 1); + YGNodeInsertChild(root1_child0_child0, root1_child0_child0_child0, 0); + + const int32_t cal1_configInstanceCount = YGConfigGetInstanceCount(); + const int32_t cal1_nodeInstanceCount = YGNodeGetInstanceCount(); + + YGNodeCalculateLayout(root1, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(YGConfigGetInstanceCount(), cal1_configInstanceCount); + ASSERT_EQ(YGNodeGetInstanceCount(), cal1_nodeInstanceCount); + + const YGNodeRef root2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root2, 500); + YGNodeStyleSetHeight(root2, 500); + + const YGNodeRef root2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root2_child0, YGAlignFlexStart); + YGNodeInsertChild(root2, root2_child0, 0); + + const YGNodeRef root2_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root2_child0_child0, 1); + YGNodeStyleSetFlexShrink(root2_child0_child0, 1); + YGNodeInsertChild(root2_child0, root2_child0_child0, 0); + + const YGNodeRef root2_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root2_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root2_child0_child0_child0, 1); + YGNodeInsertChild(root2_child0_child0, root2_child0_child0_child0, 0); + + const int32_t cal2_configInstanceCount = YGConfigGetInstanceCount(); + const int32_t cal2_nodeInstanceCount = YGNodeGetInstanceCount(); + + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(YGConfigGetInstanceCount(), cal2_configInstanceCount); + ASSERT_EQ(YGNodeGetInstanceCount(), cal2_nodeInstanceCount); + + ASSERT_TRUE(YGNodeLayoutGetDidUseLegacyFlag(root1)); + ASSERT_TRUE(YGNodeLayoutGetDidUseLegacyFlag(root2)); + ASSERT_TRUE(root1->isLayoutTreeEqualToNode(*root2)); + + YGNodeStyleSetAlignItems(root2, YGAlignFlexEnd); + + const int32_t cal3_configInstanceCount = YGConfigGetInstanceCount(); + const int32_t cal3_nodeInstanceCount = YGNodeGetInstanceCount(); + + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(YGConfigGetInstanceCount(), cal3_configInstanceCount); + ASSERT_EQ(YGNodeGetInstanceCount(), cal3_nodeInstanceCount); + + ASSERT_FALSE(root1->isLayoutTreeEqualToNode(*root2)); + + YGNodeFreeRecursive(root1); + YGNodeFreeRecursive(root2); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGLoggerTest.cpp index 0000000,1b84ee6..69efc8a mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGLoggerTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGLoggerTest.cpp @@@ -1,0 -1,87 +1,87 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + namespace { + char writeBuffer[4096]; + int _unmanagedLogger(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args) { + return vsnprintf(writeBuffer + strlen(writeBuffer), + sizeof(writeBuffer) - strlen(writeBuffer), + format, + args); + } + } + + TEST(YogaTest, logger_default_node_should_print_no_style_info) { + writeBuffer[0] = '\0'; + const YGConfigRef config = YGConfigNew(); + YGConfigSetLogger(config, _unmanagedLogger); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); + YGNodePrint(root, + (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); + YGConfigSetLogger(config, NULL); + YGNodeFree(root); + + const char *expected = "
"; + ASSERT_STREQ(expected, writeBuffer); + } + + TEST(YogaTest, logger_node_with_percentage_absolute_position_and_margin) { + writeBuffer[0] = '\0'; + const YGConfigRef config = YGConfigNew(); + YGConfigSetLogger(config, _unmanagedLogger); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root, 50); + YGNodeStyleSetHeightPercent(root, 75); + YGNodeStyleSetFlex(root, 1); + YGNodeStyleSetMargin(root, YGEdgeRight, 10); + YGNodeStyleSetMarginAuto(root, YGEdgeLeft); + YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); + YGNodePrint(root, + (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); + YGConfigSetLogger(config, NULL); + YGNodeFree(root); + + const char *expected = "
"; + ASSERT_STREQ(expected, writeBuffer); + } + + TEST(YogaTest, logger_node_with_children_should_print_indented) { + writeBuffer[0] = '\0'; + const YGConfigRef config = YGConfigNew(); + YGConfigSetLogger(config, _unmanagedLogger); + const YGNodeRef root = YGNodeNewWithConfig(config); + const YGNodeRef child0 = YGNodeNewWithConfig(config); + const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, child0, 0); + YGNodeInsertChild(root, child1, 1); + YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); + YGNodePrint(root, + (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); + YGConfigSetLogger(config, NULL); + YGNodeFreeRecursive(root); + + const char *expected = "
\n " + "
\n
\n
"; + ASSERT_STREQ(expected, writeBuffer); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGMarginTest.cpp index 0000000,593cd2f..18c72c4 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGMarginTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGMarginTest.cpp @@@ -1,0 -1,1717 +1,1717 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGMarginTest.html + + #include + #include + + TEST(YogaTest, margin_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_bottom) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_and_flex_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_and_flex_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_and_stretch_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_and_stretch_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_with_sibling_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_with_sibling_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_bottom) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_bottom_and_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_bottom_and_top_justify_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_mutiple_children_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child1, YGEdgeTop); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_mutiple_children_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child1, YGEdgeRight); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_and_right_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_and_right) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_start_and_end_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeStart); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeEnd); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_start_and_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeStart); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeEnd); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_and_right_column_and_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_right) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_and_right_strech) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_top_and_bottom_strech) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_should_not_be_part_of_max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 250); + YGNodeStyleSetHeight(root, 250); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetMaxHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_should_not_be_part_of_max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 250); + YGNodeStyleSetHeight(root, 250); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetMaxWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_right_child_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 72); + YGNodeStyleSetHeight(root_child0, 72); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_child_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetWidth(root_child0, 72); + YGNodeStyleSetHeight(root_child0, 72); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_fix_left_auto_right_child_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 72); + YGNodeStyleSetHeight(root_child0, 72); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_fix_right_child_bigger_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0, 72); + YGNodeStyleSetHeight(root_child0, 72); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_top_stretching_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, margin_auto_left_stretching_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureCacheTest.cpp index 0000000,91f1891..7c2fc33 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureCacheTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureCacheTest.cpp @@@ -1,0 -1,176 +1,176 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + static YGSize _measureMax(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + int* measureCount = (int*)node->getContext(); + (*measureCount)++; + + return YGSize{ + .width = widthMode == YGMeasureModeUndefined ? 10 : width, + .height = heightMode == YGMeasureModeUndefined ? 10 : height, + }; + } + + static YGSize _measureMin(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + int* measureCount = (int*)node->getContext(); + *measureCount = *measureCount + 1; + return YGSize{ + .width = + widthMode == YGMeasureModeUndefined || (widthMode == YGMeasureModeAtMost && width > 10) + ? 10 + : width, + .height = + heightMode == YGMeasureModeUndefined || (heightMode == YGMeasureModeAtMost && height > 10) + ? 10 + : height, + }; + } + + static YGSize _measure_84_49(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + int* measureCount = (int*)node->getContext(); + if (measureCount) { + (*measureCount)++; + } + + return YGSize{ + .width = 84.f, .height = 49.f, + }; + } + + TEST(YogaTest, measure_once_single_flexible_child) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + int measureCount = 0; + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measureMax); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, remeasure_with_same_exact_width_larger_than_needed_height) { + const YGNodeRef root = YGNodeNew(); + + const YGNodeRef root_child0 = YGNodeNew(); + int measureCount = 0; + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measureMin); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + YGNodeCalculateLayout(root, 100, 50, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, remeasure_with_same_atmost_width_larger_than_needed_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + + const YGNodeRef root_child0 = YGNodeNew(); + int measureCount = 0; + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measureMin); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + YGNodeCalculateLayout(root, 100, 50, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, remeasure_with_computed_width_larger_than_needed_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + + const YGNodeRef root_child0 = YGNodeNew(); + int measureCount = 0; + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measureMin); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + YGNodeStyleSetAlignItems(root, YGAlignStretch); + YGNodeCalculateLayout(root, 10, 50, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, remeasure_with_atmost_computed_width_undefined_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + + const YGNodeRef root_child0 = YGNodeNew(); + int measureCount = 0; + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measureMin); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 100, YGUndefined, YGDirectionLTR); + YGNodeCalculateLayout(root, 10, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, remeasure_with_already_measured_value_smaller_but_still_float_equal) { + int measureCount = 0; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 288.f); + YGNodeStyleSetHeight(root, 288.f); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPadding(root_child0, YGEdgeAll, 2.88f); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNew(); + root_child0_child0->setContext(&measureCount); + root_child0_child0->setMeasureFunc(_measure_84_49); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeFreeRecursive(root); + + ASSERT_EQ(1, measureCount); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureModeTest.cpp index 0000000,8e52894..4ff6ac3 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureModeTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureModeTest.cpp @@@ -1,0 -1,326 +1,326 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + struct _MeasureConstraint { + float width; + YGMeasureMode widthMode; + float height; + YGMeasureMode heightMode; + }; + + struct _MeasureConstraintList { + uint32_t length; + struct _MeasureConstraint *constraints; + }; + + static YGSize _measure_for_mode_test(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + struct _MeasureConstraintList* constraintList = + (struct _MeasureConstraintList*)node->getContext(); + struct _MeasureConstraint *constraints = constraintList->constraints; + uint32_t currentIndex = constraintList->length; + (&constraints[currentIndex])->width = width; + (&constraints[currentIndex])->widthMode = widthMode; + (&constraints[currentIndex])->height = height; + (&constraints[currentIndex])->heightMode = heightMode; + constraintList->length = currentIndex + 1; + + return YGSize{ + .width = widthMode == YGMeasureModeUndefined ? 10 : width, + .height = heightMode == YGMeasureModeUndefined ? 10 : width, + }; + } + + TEST(YogaTest, exactly_measure_stretched_child_column) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + // root_child0->setContext(&constraintList); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + // root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].width); + ASSERT_EQ(YGMeasureModeExactly, constraintList.constraints[0].widthMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, exactly_measure_stretched_child_row) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + // root_child0->setContext(&constraintList); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeExactly, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, at_most_main_axis_column) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, at_most_cross_axis_column) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].width); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].widthMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, at_most_main_axis_row) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].width); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].widthMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, at_most_cross_axis_row) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, flex_child) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(2, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].heightMode); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[1].height); + ASSERT_EQ(YGMeasureModeExactly, constraintList.constraints[1].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, flex_child_with_flex_basis) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 0); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeExactly, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, overflow_scroll_column) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetOverflow(root, YGOverflowScroll); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].width); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].widthMode); + + ASSERT_TRUE(YGFloatIsUndefined(constraintList.constraints[0].height)); + ASSERT_EQ(YGMeasureModeUndefined, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, overflow_scroll_row) { + struct _MeasureConstraintList constraintList = _MeasureConstraintList{ + .length = 0, + .constraints = (struct _MeasureConstraint *) malloc(10 * sizeof(struct _MeasureConstraint)), + }; + + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetOverflow(root, YGOverflowScroll); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&constraintList); + root_child0->setMeasureFunc(_measure_for_mode_test); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, constraintList.length); + + ASSERT_TRUE(YGFloatIsUndefined(constraintList.constraints[0].width)); + ASSERT_EQ(YGMeasureModeUndefined, constraintList.constraints[0].widthMode); + + ASSERT_FLOAT_EQ(100, constraintList.constraints[0].height); + ASSERT_EQ(YGMeasureModeAtMost, constraintList.constraints[0].heightMode); + + free(constraintList.constraints); + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureTest.cpp index 0000000,aea2cd5..5396728 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGMeasureTest.cpp @@@ -1,0 -1,689 +1,689 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + static YGSize _measure(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + int* measureCount = (int*)node->getContext(); + if (measureCount) { + (*measureCount)++; + } + + return YGSize{ + .width = 10, .height = 10, + }; + } + + static YGSize _simulate_wrapping_text(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + if (widthMode == YGMeasureModeUndefined || width >= 68) { + return YGSize{.width = 68, .height = 16}; + } + + return YGSize{ + .width = 50, .height = 32, + }; + } + + static YGSize _measure_assert_negative(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + EXPECT_GE(width, 0); + EXPECT_GE(height, 0); + + return YGSize{ + .width = 0, .height = 0, + }; + } + + TEST(YogaTest, dont_measure_single_grow_shrink_child) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, measure_absolute_child_with_no_constraints) { + const YGNodeRef root = YGNodeNew(); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeInsertChild(root, root_child0, 0); + + int measureCount = 0; + + const YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + root_child0_child0->setContext(&measureCount); + root_child0_child0->setMeasureFunc(_measure); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dont_measure_when_min_equals_max) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetMinWidth(root_child0, 10); + YGNodeStyleSetMaxWidth(root_child0, 10); + YGNodeStyleSetMinHeight(root_child0, 10); + YGNodeStyleSetMaxHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, measureCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dont_measure_when_min_equals_max_percentages) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetMinWidthPercent(root_child0, 10); + YGNodeStyleSetMaxWidthPercent(root_child0, 10); + YGNodeStyleSetMinHeightPercent(root_child0, 10); + YGNodeStyleSetMaxHeightPercent(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, measureCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + + TEST(YogaTest, measure_nodes_with_margin_auto_and_stretch) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_EQ(490, YGNodeLayoutGetLeft(root_child0)); + EXPECT_EQ(0, YGNodeLayoutGetTop(root_child0)); + EXPECT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + EXPECT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dont_measure_when_min_equals_max_mixed_width_percent) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetMinWidthPercent(root_child0, 10); + YGNodeStyleSetMaxWidthPercent(root_child0, 10); + YGNodeStyleSetMinHeight(root_child0, 10); + YGNodeStyleSetMaxHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, measureCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, dont_measure_when_min_equals_max_mixed_height_percent) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + YGNodeStyleSetMinWidth(root_child0, 10); + YGNodeStyleSetMaxWidth(root_child0, 10); + YGNodeStyleSetMinHeightPercent(root_child0, 10); + YGNodeStyleSetMaxHeightPercent(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, measureCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, measure_enough_size_should_be_in_single_line) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); + root_child0->setMeasureFunc(_simulate_wrapping_text); + + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(68, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, measure_not_enough_size_should_wrap) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 55); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); + // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, measure_zero_space_should_grow) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetFlexGrow(root, 0); + + int measureCount = 0; + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn); + YGNodeStyleSetPadding(root_child0, YGEdgeAll, 100); + root_child0->setContext(&measureCount); + root_child0->setMeasureFunc(_measure); + + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 282, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(282, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, measure_flex_direction_row_and_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPadding(root, YGEdgeLeft, 25); + YGNodeStyleSetPadding(root, YGEdgeTop, 25); + YGNodeStyleSetPadding(root, YGEdgeRight, 25); + YGNodeStyleSetPadding(root, YGEdgeBottom, 25); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_flex_direction_column_and_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeAll, 25); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(57, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_flex_direction_row_no_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_flex_direction_row_no_padding_align_items_flexstart) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_with_fixed_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeAll, 25); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_with_flex_shrink) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeAll, 25); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, measure_no_padding) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, 20); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 5); + YGNodeStyleSetHeight(root_child1, 5); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(32, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + #if GTEST_HAS_DEATH_TEST + TEST(YogaDeathTest, cannot_add_child_to_node_with_measure_func) { + const YGNodeRef root = YGNodeNew(); + root->setMeasureFunc(_measure); + + const YGNodeRef root_child0 = YGNodeNew(); + ASSERT_DEATH(YGNodeInsertChild(root, root_child0, 0), "Cannot add child.*"); + YGNodeFree(root_child0); + YGNodeFreeRecursive(root); + } + + TEST(YogaDeathTest, cannot_add_nonnull_measure_func_to_non_leaf_node) { + const YGNodeRef root = YGNodeNew(); + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeInsertChild(root, root_child0, 0); + ASSERT_DEATH(root->setMeasureFunc(_measure), "Cannot set measure function.*"); + YGNodeFreeRecursive(root); + } + + #endif + + TEST(YogaTest, can_nullify_measure_func_on_any_node) { + const YGNodeRef root = YGNodeNew(); + YGNodeInsertChild(root, YGNodeNew(), 0); + root->setMeasureFunc(nullptr); + ASSERT_TRUE(root->getMeasure() == NULL); + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, cant_call_negative_measure) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 10); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_measure_assert_negative); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeFreeRecursive(root); + YGConfigFree(config); + } + + TEST(YogaTest, cant_call_negative_measure_horizontal) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 10); + YGNodeStyleSetHeight(root, 20); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_measure_assert_negative); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeFreeRecursive(root); + YGConfigFree(config); + } + + static YGSize _measure_90_10(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + + return YGSize{ + .width = 90, .height = 10, + }; + } + + TEST(YogaTest, percent_with_text_node) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 80); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + root_child1->setMeasureFunc(_measure_90_10); + YGNodeStyleSetMaxWidthPercent(root_child1, 50); + YGNodeStyleSetPaddingPercent(root_child1, YGEdgeTop, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGMinMaxDimensionTest.cpp index 0000000,515bdfd..31f0126 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGMinMaxDimensionTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGMinMaxDimensionTest.cpp @@@ -1,0 -1,1297 +1,1297 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGMinMaxDimensionTest.html + + #include + #include + + TEST(YogaTest, max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMaxWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetMaxHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, min_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, min_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinWidth(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_min_max) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, align_items_min_max) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetMinWidth(root, 100); + YGNodeStyleSetMaxWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, justify_content_overflow_min_max) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 110); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_to_min) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_in_at_most_container) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexBasis(root_child0_child0, 0); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 0); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_min_max_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxWidth(root_child0, 300); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_root_ignored) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root, 1); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_root_minimized) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMinHeight(root, 100); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinHeight(root_child0, 100); + YGNodeStyleSetMaxHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexBasis(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_height_maximized) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinHeight(root_child0, 100); + YGNodeStyleSetMaxHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexBasis(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_min_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetMinWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_min_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMinHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_max_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasis(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, flex_grow_within_constrained_max_column) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMaxHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, child_min_max_width_flexing) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 120); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 0); + YGNodeStyleSetMinWidth(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 50); + YGNodeStyleSetMaxWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, min_width_overrides_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetMinWidth(root, 100); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, max_width_overrides_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetMaxWidth(root, 100); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, min_height_overrides_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root, 50); + YGNodeStyleSetMinHeight(root, 100); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, max_height_overrides_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetMaxHeight(root, 100); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, min_max_percent_no_width_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMinWidthPercent(root_child0, 10); + YGNodeStyleSetMaxWidthPercent(root_child0, 10); + YGNodeStyleSetMinHeightPercent(root_child0, 10); + YGNodeStyleSetMaxHeightPercent(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGNodeChildTest.cpp index 0000000,9d6bb48..417d258 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGNodeChildTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGNodeChildTest.cpp @@@ -1,0 -1,34 +1,34 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, reset_layout_when_child_removed) { + const YGNodeRef root = YGNodeNew(); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeRemoveChild(root, root_child0); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeLayoutGetWidth(root_child0))); + ASSERT_TRUE(YGFloatIsUndefined(YGNodeLayoutGetHeight(root_child0))); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGPaddingTest.cpp index 0000000,f0d3752..741e0d5 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGPaddingTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGPaddingTest.cpp @@@ -1,0 -1,258 +1,258 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGPaddingTest.html + + #include + #include + + TEST(YogaTest, padding_no_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, padding_container_match_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, padding_flex_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, padding_stretch_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, padding_center_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPadding(root, YGEdgeStart, 10); + YGNodeStyleSetPadding(root, YGEdgeEnd, 20); + YGNodeStyleSetPadding(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, child_with_padding_align_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 20); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 20); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 20); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGPercentageTest.cpp index 0000000,2be0459..533833e mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGPercentageTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGPercentageTest.cpp @@@ -1,0 -1,1194 +1,1194 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html + + #include + #include + + TEST(YogaTest, percentage_width_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 30); + YGNodeStyleSetHeightPercent(root_child0, 30); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_position_left_top) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 400); + YGNodeStyleSetHeight(root, 400); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 20); + YGNodeStyleSetWidthPercent(root_child0, 45); + YGNodeStyleSetHeightPercent(root_child0, 55); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(260, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_position_bottom_right) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeRight, 20); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidthPercent(root_child0, 55); + YGNodeStyleSetHeightPercent(root_child0, 15); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(275, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(275, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_cross) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_cross_min_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinHeightPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 2); + YGNodeStyleSetMinHeightPercent(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_main_max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 10); + YGNodeStyleSetMaxHeightPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 10); + YGNodeStyleSetMaxHeightPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(148, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(148, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(148, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_cross_max_height) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 10); + YGNodeStyleSetMaxHeightPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 10); + YGNodeStyleSetMaxHeightPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_main_max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 15); + YGNodeStyleSetMaxWidthPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 10); + YGNodeStyleSetMaxWidthPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_cross_max_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 10); + YGNodeStyleSetMaxWidthPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 15); + YGNodeStyleSetMaxWidthPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_main_min_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 15); + YGNodeStyleSetMinWidthPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 10); + YGNodeStyleSetMinWidthPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_flex_basis_cross_min_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 10); + YGNodeStyleSetMinWidthPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 15); + YGNodeStyleSetMinWidthPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_multiple_nested_with_padding_margin_and_percentage_values) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 10); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 3); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 3); + YGNodeStyleSetMinWidthPercent(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 5); + YGNodeStyleSetPaddingPercent(root_child0_child0, YGEdgeLeft, 3); + YGNodeStyleSetPaddingPercent(root_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPaddingPercent(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetPaddingPercent(root_child0_child0, YGEdgeBottom, 3); + YGNodeStyleSetWidthPercent(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 5); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeBottom, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 3); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 45); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 4); + YGNodeStyleSetFlexBasisPercent(root_child1, 15); + YGNodeStyleSetMinWidthPercent(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(48, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(6, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(58, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(142, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(48, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(46, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(36, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(6, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(58, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(142, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_margin_should_calculate_based_only_on_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMarginPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetMarginPercent(root_child0, YGEdgeTop, 10); + YGNodeStyleSetMarginPercent(root_child0, YGEdgeRight, 10); + YGNodeStyleSetMarginPercent(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_padding_should_calculate_based_only_on_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeRight, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_absolute_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 30); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_width_height_undefined_parent_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetHeightPercent(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percent_within_flex_grow) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 350); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child1_child0, 100); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(350, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(350, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percentage_container_in_wrapping_container) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); + YGNodeStyleSetWidthPercent(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + const YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child0_child1, 50); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, percent_absolute_position) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 50); + YGNodeStyleSetWidthPercent(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-60, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGPersistenceTest.cpp index 0000000,9df861a..8567755 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGPersistenceTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGPersistenceTest.cpp @@@ -1,0 -1,250 +1,250 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html + + #include + #include + + TEST(YogaTest, cloning_shared_root) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + const YGNodeRef root2 = YGNodeClone(root); + YGNodeStyleSetWidth(root2, 100); + + ASSERT_EQ(2, YGNodeGetChildCount(root2)); + // The children should have referential equality at this point. + ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0)); + ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1)); + + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(2, YGNodeGetChildCount(root2)); + // Relayout with no changed input should result in referential equality. + ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0)); + ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1)); + + YGNodeStyleSetWidth(root2, 150); + YGNodeStyleSetHeight(root2, 200); + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(2, YGNodeGetChildCount(root2)); + // Relayout with changed input should result in cloned children. + const YGNodeRef root2_child0 = YGNodeGetChild(root2, 0); + const YGNodeRef root2_child1 = YGNodeGetChild(root2, 1); + ASSERT_NE(root_child0, root2_child0); + ASSERT_NE(root_child1, root2_child1); + + // Everything in the root should remain unchanged. + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + // The new root now has new layout. + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetHeight(root2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child1)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root2_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root2_child1)); + + YGNodeFreeRecursive(root2); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, mutating_children_of_a_clone_clones) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + ASSERT_EQ(0, YGNodeGetChildCount(root)); + + const YGNodeRef root2 = YGNodeClone(root); + ASSERT_EQ(0, YGNodeGetChildCount(root2)); + + const YGNodeRef root2_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root2, root2_child0, 0); + + ASSERT_EQ(0, YGNodeGetChildCount(root)); + ASSERT_EQ(1, YGNodeGetChildCount(root2)); + + const YGNodeRef root3 = YGNodeClone(root2); + ASSERT_EQ(1, YGNodeGetChildCount(root2)); + ASSERT_EQ(1, YGNodeGetChildCount(root3)); + ASSERT_EQ(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0)); + + const YGNodeRef root3_child1 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root3, root3_child1, 1); + ASSERT_EQ(1, YGNodeGetChildCount(root2)); + ASSERT_EQ(2, YGNodeGetChildCount(root3)); + ASSERT_EQ(root3_child1, YGNodeGetChild(root3, 1)); + ASSERT_NE(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0)); + + const YGNodeRef root4 = YGNodeClone(root3); + ASSERT_EQ(root3_child1, YGNodeGetChild(root4, 1)); + + YGNodeRemoveChild(root4, root3_child1); + ASSERT_EQ(2, YGNodeGetChildCount(root3)); + ASSERT_EQ(1, YGNodeGetChildCount(root4)); + ASSERT_NE(YGNodeGetChild(root3, 0), YGNodeGetChild(root4, 0)); + + YGNodeFreeRecursive(root4); + YGNodeFreeRecursive(root3); + YGNodeFreeRecursive(root2); + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, cloning_two_levels) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 15); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1_0, 10); + YGNodeStyleSetFlexGrow(root_child1_0, 1); + YGNodeInsertChild(root_child1, root_child1_0, 0); + + const YGNodeRef root_child1_1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1_1, 25); + YGNodeInsertChild(root_child1, root_child1_1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1)); + + const YGNodeRef root2_child0 = YGNodeClone(root_child0); + const YGNodeRef root2_child1 = YGNodeClone(root_child1); + const YGNodeRef root2 = YGNodeClone(root); + + YGNodeStyleSetFlexGrow(root2_child0, 0); + YGNodeStyleSetFlexBasis(root2_child0, 40); + + YGNodeRemoveAllChildren(root2); + YGNodeInsertChild(root2, root2_child0, 0); + YGNodeInsertChild(root2, root2_child1, 1); + ASSERT_EQ(2, YGNodeGetChildCount(root2)); + + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + // Original root is unchanged + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1)); + + // New root has new layout at the top + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root2_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root2_child1)); + + // The deeper children are untouched. + ASSERT_EQ(YGNodeGetChild(root2_child1, 0), root_child1_0); + ASSERT_EQ(YGNodeGetChild(root2_child1, 1), root_child1_1); + + YGNodeFreeRecursive(root2); + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, cloning_and_freeing) { + const int32_t initialInstanceCount = YGNodeGetInstanceCount(); + + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + const YGNodeRef root2 = YGNodeClone(root); + + // Freeing the original root should be safe as long as we don't free its + // children. + YGNodeFree(root); + + YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeFreeRecursive(root2); + + YGNodeFree(root_child0); + YGNodeFree(root_child1); + + YGConfigFree(config); + + ASSERT_EQ(initialInstanceCount, YGNodeGetInstanceCount()); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGRelayoutTest.cpp index 0000000,cbda524..8add427 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGRelayoutTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGRelayoutTest.cpp @@@ -1,0 -1,50 +1,50 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, dont_cache_computed_flex_basis_between_layouts) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetHeightPercent(root, 100); + YGNodeStyleSetWidthPercent(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasisPercent(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, 100, YGUndefined, YGDirectionLTR); + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, recalculate_resolvedDimonsion_onchange) { + const YGNodeRef root = YGNodeNew(); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMinHeight(root_child0, 10); + YGNodeStyleSetMaxHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeStyleSetMinHeight(root_child0, YGUndefined); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingFunctionTest.cpp index 0000000,82eba44..a6c10da mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingFunctionTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingFunctionTest.cpp @@@ -1,0 -1,28 +1,28 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + TEST(YogaTest, rounding_value) { + // Test that whole numbers are rounded to whole despite ceil/floor flags + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, false, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, true, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, false, true)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, false, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, true, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, false, true)); + + // Test that numbers with fraction are rounded correctly accounting for ceil/floor flags + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.01, 2.0, false, false)); + ASSERT_FLOAT_EQ(6.5, YGRoundValueToPixelGrid(6.01, 2.0, true, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.01, 2.0, false, true)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.99, 2.0, false, false)); + ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.99, 2.0, true, false)); + ASSERT_FLOAT_EQ(5.5, YGRoundValueToPixelGrid(5.99, 2.0, false, true)); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingMeasureFuncTest.cpp index 0000000,33820c4..a978d91 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingMeasureFuncTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingMeasureFuncTest.cpp @@@ -1,0 -1,130 +1,130 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + static YGSize _measureFloor(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + return YGSize{ + width = 10.2f, height = 10.2f, + }; + } + + static YGSize _measureCeil(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + return YGSize{ + width = 10.5f, height = 10.5f, + }; + } + + static YGSize _measureFractial(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + return YGSize{ + width = 0.5f, height = 0.5f, + }; + } + + TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) { + const YGConfigRef config = YGConfigNew(); + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_measureFloor); + YGNodeInsertChild(root, root_child0, 0); + + YGConfigSetPointScaleFactor(config, 0.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetHeight(root_child0)); + + YGConfigSetPointScaleFactor(config, 1.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetHeight(root_child0)); + + YGConfigSetPointScaleFactor(config, 2.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(10.5, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10.5, YGNodeLayoutGetHeight(root_child0)); + + YGConfigSetPointScaleFactor(config, 4.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetHeight(root_child0)); + + YGConfigSetPointScaleFactor(config, 1.0f / 3.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(12.0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(12.0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_feature_with_custom_measure_func_ceil) { + const YGConfigRef config = YGConfigNew(); + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + root_child0->setMeasureFunc(_measureCeil); + YGNodeInsertChild(root, root_child0, 0); + + YGConfigSetPointScaleFactor(config, 1.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_feature_with_custom_measure_and_fractial_matching_scale) { + const YGConfigRef config = YGConfigNew(); + const YGNodeRef root = YGNodeNewWithConfig(config); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 73.625); + root_child0->setMeasureFunc(_measureFractial); + YGNodeInsertChild(root, root_child0, 0); + + YGConfigSetPointScaleFactor(config, 2.0f); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0.5, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0.5, YGNodeLayoutGetHeight(root_child0)); + ASSERT_FLOAT_EQ(73.5, YGNodeLayoutGetLeft(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingTest.cpp index 0000000,303e9f0..0ec295c mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGRoundingTest.cpp @@@ -1,0 -1,1077 +1,1077 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGRoundingTest.html + + #include + #include + + TEST(YogaTest, rounding_flex_basis_flex_grow_row_width_of_100) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(34, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(67, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(67, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(34, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_flex_basis_flex_grow_row_prime_number_width) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 113); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child4, 1); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(68, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(68, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_flex_basis_flex_shrink_row) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 101); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child2, 25); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(101, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(51, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(51, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(76, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(101, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(51, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_flex_basis_overrides_main_size) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 113); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_total_fractial) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 87.4f); + YGNodeStyleSetHeight(root, 113.4f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 0.7f); + YGNodeStyleSetFlexBasis(root_child0, 50.3f); + YGNodeStyleSetHeight(root_child0, 20.3f); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1.6f); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1.1f); + YGNodeStyleSetHeight(root_child2, 10.7f); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_total_fractial_nested) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 87.4f); + YGNodeStyleSetHeight(root, 113.4f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 0.7f); + YGNodeStyleSetFlexBasis(root_child0, 50.3f); + YGNodeStyleSetHeight(root_child0, 20.3f); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexBasis(root_child0_child0, 0.3f); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeBottom, 13.3f); + YGNodeStyleSetHeight(root_child0_child0, 9.9f); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 4); + YGNodeStyleSetFlexBasis(root_child0_child1, 0.3f); + YGNodeStyleSetPosition(root_child0_child1, YGEdgeTop, 13.3f); + YGNodeStyleSetHeight(root_child0_child1, 1.1f); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1.6f); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1.1f); + YGNodeStyleSetHeight(root_child2, 10.7f); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-13, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(47, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-13, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(47, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(87, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_fractial_input_1) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 113.4f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_fractial_input_2) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 113.6f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(114, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(114, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_fractial_input_3) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root, YGEdgeTop, 0.3f); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 113.4f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(114, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(114, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_fractial_input_4) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root, YGEdgeTop, 0.7f); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 113.4f); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(113, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(64, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(89, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_inner_node_controversy_horizontal) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 320); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child0, 1); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_inner_node_controversy_vertical) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root, 320); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child0, 1); + YGNodeStyleSetWidth(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, rounding_inner_node_controversy_combined) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 640); + YGNodeStyleSetHeight(root, 320); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetHeightPercent(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetHeightPercent(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child0, 1); + YGNodeStyleSetWidthPercent(root_child1_child0, 100); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child1, 1); + YGNodeStyleSetWidthPercent(root_child1_child1, 100); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child1_child0, 1); + YGNodeStyleSetWidthPercent(root_child1_child1_child0, 100); + YGNodeInsertChild(root_child1_child1, root_child1_child1_child0, 0); + + const YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child2, 1); + YGNodeStyleSetWidthPercent(root_child1_child2, 100); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetHeightPercent(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(640, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(427, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(640, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(427, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child1_child0)); + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetHeight(root_child1_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(214, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(107, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(320, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGSizeOverflowTest.cpp index 0000000,3fbcb30..6ecb798 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGSizeOverflowTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGSizeOverflowTest.cpp @@@ -1,0 -1,173 +1,173 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGSizeOverflowTest.html + + #include + #include + + TEST(YogaTest, nested_overflowing_child) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, nested_overflowing_child_in_constraint_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } + + TEST(YogaTest, parent_wrap_child_size_overflowing_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGStyleTest.cpp index 0000000,08b7be2..8bb85ee mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGStyleTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGStyleTest.cpp @@@ -1,0 -1,82 +1,82 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + #include + + TEST(YogaTest, copy_style_same) { + const YGNodeRef node0 = YGNodeNew(); + const YGNodeRef node1 = YGNodeNew(); + ASSERT_FALSE(node0->isDirty()); + + YGNodeCopyStyle(node0, node1); + ASSERT_FALSE(node0->isDirty()); + + YGNodeFree(node0); + YGNodeFree(node1); + } + + TEST(YogaTest, copy_style_modified) { + const YGNodeRef node0 = YGNodeNew(); + ASSERT_FALSE(node0->isDirty()); + ASSERT_EQ(YGFlexDirectionColumn, YGNodeStyleGetFlexDirection(node0)); + ASSERT_FALSE(YGNodeStyleGetMaxHeight(node0).unit != YGUnitUndefined); + + const YGNodeRef node1 = YGNodeNew(); + YGNodeStyleSetFlexDirection(node1, YGFlexDirectionRow); + YGNodeStyleSetMaxHeight(node1, 10); + + YGNodeCopyStyle(node0, node1); + ASSERT_TRUE(node0->isDirty()); + ASSERT_EQ(YGFlexDirectionRow, YGNodeStyleGetFlexDirection(node0)); + ASSERT_FLOAT_EQ(10, YGNodeStyleGetMaxHeight(node0).value); + + YGNodeFree(node0); + YGNodeFree(node1); + } + + TEST(YogaTest, copy_style_modified_same) { + const YGNodeRef node0 = YGNodeNew(); + YGNodeStyleSetFlexDirection(node0, YGFlexDirectionRow); + YGNodeStyleSetMaxHeight(node0, 10); + YGNodeCalculateLayout(node0, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FALSE(node0->isDirty()); + + const YGNodeRef node1 = YGNodeNew(); + YGNodeStyleSetFlexDirection(node1, YGFlexDirectionRow); + YGNodeStyleSetMaxHeight(node1, 10); + + YGNodeCopyStyle(node0, node1); + ASSERT_FALSE(node0->isDirty()); + + YGNodeFree(node0); + YGNodeFree(node1); + } + + TEST(YogaTest, initialise_flexShrink_flexGrow) { + const YGNodeRef node0 = YGNodeNew(); + YGNodeStyleSetFlexShrink(node0, 1); + ASSERT_EQ(1, YGNodeStyleGetFlexShrink(node0)); + + YGNodeStyleSetFlexShrink(node0, YGUndefined); + YGNodeStyleSetFlexGrow(node0, 3); + ASSERT_EQ( + 0, + YGNodeStyleGetFlexShrink( + node0)); // Default value is Zero, if flex shrink is not defined + ASSERT_EQ(3, YGNodeStyleGetFlexGrow(node0)); + + YGNodeStyleSetFlexGrow(node0, YGUndefined); + YGNodeStyleSetFlexShrink(node0, 3); + ASSERT_EQ( + 0, + YGNodeStyleGetFlexGrow( + node0)); // Default value is Zero, if flex grow is not defined + ASSERT_EQ(3, YGNodeStyleGetFlexShrink(node0)); + YGNodeFree(node0); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGTraversalTest.cpp index 0000000,3c4771d..eb5b89b mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGTraversalTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGTraversalTest.cpp @@@ -1,0 -1,34 +1,34 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, pre_order_traversal) { + YGNodeRef const root = YGNodeNew(); + YGNodeRef const root_child0 = YGNodeNew(); + YGNodeRef const root_child1 = YGNodeNew(); + YGNodeRef const root_child0_child0 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child0, root_child1}); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + std::vector visited; + YGTraversePreOrder(root, [&visited](YGNodeRef node) { + visited.push_back(node); + }); + + const std::vector expected = { + root, + root_child0, + root_child0_child0, + root_child1 + }; + ASSERT_EQ(visited, expected); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGTreeMutationTest.cpp index 0000000,273f22a..373a3c7 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGTreeMutationTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGTreeMutationTest.cpp @@@ -1,0 -1,111 +1,111 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + static std::vector getChildren(YGNodeRef const node) + { + const uint32_t count = YGNodeGetChildCount(node); + std::vector children; + children.reserve(count); + for (uint32_t i = 0 ; i < count ; i++) { + children.push_back(YGNodeGetChild(node, i)); + } + return children; + } + + TEST(YogaTest, set_children_adds_children_to_parent) { + YGNodeRef const root = YGNodeNew(); + YGNodeRef const root_child0 = YGNodeNew(); + YGNodeRef const root_child1 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child0, root_child1}); + + const std::vector children = getChildren(root); + const std::vector expectedChildren = {root_child0, root_child1}; + ASSERT_EQ(children, expectedChildren); + + const std::vector owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; + const std::vector expectedOwners = {root, root}; + ASSERT_EQ(owners, expectedOwners); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, set_children_to_empty_removes_old_children) { + YGNodeRef const root = YGNodeNew(); + YGNodeRef const root_child0 = YGNodeNew(); + YGNodeRef const root_child1 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child0, root_child1}); + YGNodeSetChildren(root, {}); + + const std::vector children = getChildren(root); + const std::vector expectedChildren = {}; + ASSERT_EQ(children, expectedChildren); + + const std::vector owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; + const std::vector expectedOwners = {nullptr, nullptr}; + ASSERT_EQ(owners, expectedOwners); + + YGNodeFreeRecursive(root); + } + + TEST(YogaTest, set_children_replaces_non_common_children) { + YGNodeRef const root = YGNodeNew(); + YGNodeRef const root_child0 = YGNodeNew(); + YGNodeRef const root_child1 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child0, root_child1}); + + YGNodeRef const root_child2 = YGNodeNew(); + YGNodeRef const root_child3 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child2, root_child3}); + + const std::vector children = getChildren(root); + const std::vector expectedChildren = {root_child2, root_child3}; + ASSERT_EQ(children, expectedChildren); + + const std::vector owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; + const std::vector expectedOwners = {nullptr, nullptr}; + ASSERT_EQ(owners, expectedOwners); + + YGNodeFreeRecursive(root); + YGNodeFree(root_child0); + YGNodeFree(root_child1); + } + + TEST(YogaTest, set_children_keeps_and_reorders_common_children) { + YGNodeRef const root = YGNodeNew(); + YGNodeRef const root_child0 = YGNodeNew(); + YGNodeRef const root_child1 = YGNodeNew(); + YGNodeRef const root_child2 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child0, root_child1, root_child2}); + + YGNodeRef const root_child3 = YGNodeNew(); + + YGNodeSetChildren(root, {root_child2, root_child1, root_child3}); + + const std::vector children = getChildren(root); + const std::vector expectedChildren = {root_child2, root_child1, root_child3}; + ASSERT_EQ(children, expectedChildren); + + const std::vector owners = { + YGNodeGetOwner(root_child0), + YGNodeGetOwner(root_child1), + YGNodeGetOwner(root_child2), + YGNodeGetOwner(root_child3) + }; + const std::vector expectedOwners = {nullptr, root, root, root}; + ASSERT_EQ(owners, expectedOwners); + + YGNodeFreeRecursive(root); + YGNodeFree(root_child0); + } diff --cc automated-tests/src/dali-toolkit-third-party/yoga/YGZeroOutLayoutRecursivlyTest.cpp index 0000000,92e7c8a..38d8ea1 mode 000000,100644..100644 --- a/automated-tests/src/dali-toolkit-third-party/yoga/YGZeroOutLayoutRecursivlyTest.cpp +++ b/automated-tests/src/dali-toolkit-third-party/yoga/YGZeroOutLayoutRecursivlyTest.cpp @@@ -1,0 -1,37 +1,37 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include + #include + + TEST(YogaTest, zero_out_layout) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef child = YGNodeNew(); + YGNodeInsertChild(root, child, 0); + YGNodeStyleSetWidth(child, 100); + YGNodeStyleSetHeight(child, 100); + YGNodeStyleSetMargin(child, YGEdgeTop, 10); + YGNodeStyleSetPadding(child, YGEdgeTop, 10); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(child, YGEdgeTop)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetPadding(child, YGEdgeTop)); + + YGNodeStyleSetDisplay(child, YGDisplayNone); + + YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(child, YGEdgeTop)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(child, YGEdgeTop)); + + YGNodeFreeRecursive(root); + } diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.h index 50a5828,32dac4b..2db5521 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEST_SUITE_UTILS_H__ /* -- * Copyright (c) 2014 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp index 3461f0d,96699ec..f635aa6 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h index d0387d9,5988284..c25aaf6 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEST_DUMMY_CONTROL_H__ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp index 54a69bb,8bb7176..9b2cd67 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h index 2e5a2cb,e5d4a70..4203015 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_ADAPTOR_IMPL_H__ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp index 4b25c5d,3ff177c..e29945e --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp @@@ -1,5 -1,5 +1,5 @@@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp index e7fb2cf,52e2d41..fe9cc44 mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-Button.cpp index d01f3b0,e9c092d..60631ea --- a/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index 53b3fbd,df48a7d..43d5990 mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-FlexContainer.cpp index f602079,26e9585..9ef6d9e mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-FlexContainer.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-FlexContainer.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index c8cf88f,c9cbdc5..bdded9a --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp index f574485,4623958..47683df mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp index becbaaa,8b9547a..c566d36 mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-Popup.cpp index 3e50df3,b190b5f..30c426f mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-Popup.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Popup.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp index 590614e,3a8ce20..49e3d92 --- a/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2014 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp index 8baed37,03da3ff..0fc5c51 mode 100644,100755..100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc build/tizen/configure.ac index 26be349,96c78cd..50a4bcd --- a/build/tizen/configure.ac +++ b/build/tizen/configure.ac @@@ -1,5 -1,5 +1,5 @@@ # --# Copyright (c) 2016 Samsung Electronics Co., Ltd. ++# Copyright (c) 2018 Samsung Electronics Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --cc dali-toolkit/devel-api/text/text-enumerations-devel.h index 0000000,4e9b278..8722d2c mode 000000,100644..100644 --- a/dali-toolkit/devel-api/text/text-enumerations-devel.h +++ b/dali-toolkit/devel-api/text/text-enumerations-devel.h @@@ -1,0 -1,59 +1,59 @@@ + #ifndef DALI_TOOLKIT_TEXT_ENUMERATIONS_DEVEL_H + #define DALI_TOOLKIT_TEXT_ENUMERATIONS_DEVEL_H + + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + namespace Dali + { + + namespace Toolkit + { + + namespace DevelText + { + + namespace TextDirection + { + + enum Type + { + LEFT_TO_RIGHT, + RIGHT_TO_LEFT + }; + + } // namespace TextDirection + + namespace VerticalLineAlignment + { + + enum Type + { + TOP, + MIDDLE, + BOTTOM + }; + + } // namespace VerticalLineAlignment + + } // namespace DevelText + + } // namespace Toolkit + + } // namespace Dali + + #endif //DALI_TOOLKIT_TEXT_ENUMERATIONS_DEVEL_H diff --cc dali-toolkit/devel-api/visual-factory/visual-factory.cpp index b91d79d,666a2a1..ba5c3cb --- a/dali-toolkit/devel-api/visual-factory/visual-factory.cpp +++ b/dali-toolkit/devel-api/visual-factory/visual-factory.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h index 0000000,41b3f31..4f59b2f mode 000000,100755..100755 --- a/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h @@@ -1,0 -1,347 +1,347 @@@ + #ifndef DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H + #define DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H + + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + // INTERNAL INCLUDES + #include + + namespace Dali + { + + namespace Toolkit + { + + /** + * + */ + + /** + * @brief AnimatedGradientVisual is to render a smooth transition of colors to the control's quad with animation. + */ + namespace DevelAnimatedGradientVisual + { + + /** + * @brief AnimatedGradientVisual Property + */ + namespace Property + { + + /** + * @brief AnimatedGradientVisual Property + */ + enum + { + /** + * @brief The form of gradient. + * @details Name "gradientType", type GradientType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is GradientType::LINEAR. + * @see GradientType::Type + */ + GRADIENT_TYPE = VISUAL_PROPERTY_START_INDEX, + + /** + * @brief The coordinate system inside of control's quad. + * @details Name "unitType", type UnitType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is UnitType::OBJECT_BOUNDING_BOX. + * @see UnitType::Type + */ + UNIT_TYPE, + + /** + * @brief The policy of color when gradient coordinate is not between 0 and 1. + * @details Name "spreadType", type SpreadType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is SpreadType::REFLECT. + * @see SpreadType::Type + */ + SPREAD_TYPE, + + /** + * @brief The position of a gradient coordinate is 0. If GRADIENT_TYPE is RADIAL, than it will be center of circle. + * @details Name "startPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + * @note If not supplied, default is Vector2( -0.5f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + START_POSITION, + + /** + * @brief The color of a gradient coordinate is 0. + * @details Name "startColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector4( 143.0f, 170.0f, 220.0f, 255.0f ) / 255.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + START_COLOR, + + /** + * @brief The position of a gradient coordinate is 1. + * @details Name "endPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector2( 0.5f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + END_POSITION, + + /** + * @brief The color of a gradient coordinate is 1. + * @details Name "endColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector4( 255.0f, 163.0f, 163.0f, 255.0f ) / 255.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + END_COLOR, + + /** + * @brief The center of rotate START_POSITION and END_POSITION. + * @details Name "rotateCenter", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Vector2( 0.0f, 0.0f ). + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + ROTATE_CENTER, + + /** + * @brief The amount of rotate START_POSITION and END_POSITION in radian. + * @details Name "rotateAmount", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is 0.0f. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property + */ + ROTATE_AMOUNT, + + /** + * @brief The offset of gradient coordinate. The point will have a color where (gradient coordinate + offset). + * @details Name "offset", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + * @note If not supplied, default is Animation from 0.0f to 2.0f, with duration 3.0f seconds. + * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property. + */ + OFFSET + }; + + } // namespace Property + + /** + * @brief The type of gradient form. It decide the method of calculate gradient coordinate. + * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION. + * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION. + */ + namespace GradientType + { + + /** + * @brief The type of gradient form. It decide the method of calculate gradient coordinate. + * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION. + * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION. + */ + enum Type + { + LINEAR, ///< Draw gradient linear form. + RADIAL ///< Draw gradient radial form. + }; + + } // namespace GradientType + + /** + * @brief The type of coordinate system for certain attributes of the points in a gradients. + * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER. + */ + namespace UnitType + { + + /** + * @brief The type of coordinate system for certain attributes of the points in a gradients. + * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER. + */ + enum Type + { + OBJECT_BOUNDING_BOX, ///< Use positions coordinate in bottom-left(-0.5,-0.5) ~ top-right(0.5,0.5). + USER_SPACE, ///< Use positions coordinate in bottom-left(-ActorSize.xy * 0.5) ~ top-right(ActorSize.xy * 0.5). + }; + + } // namespace UnitType + + /** + * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1. + */ + namespace SpreadType + { + + /** + * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1. + */ + enum Type + { + REFLECT, ///< Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. + REPEAT, ///< Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. + CLAMP, ///< Use the terminal colors of gradient. + }; + + } // namespace SpreadType + + /** + * @brief AnimatedGradientVisual::AnimationParameter is information of each properties animation. + * Value animate from start to target during duration seconds. + * Each start/target value type for AnimatedGradientVisual Property is : + * - START_POSITION, END_POSITION, ROTATE_CENTER is Property::Vector2 + * - START_COLOR, END_COLOR is Property::Vector4 + * - ROTATE_AMOUNT, OFFSET is Property::FLOAT + * You can set the animation information to AnimatedGradientVisual Property by using Property::MAP. + */ + namespace AnimationParameter + { + + /** + * @brief AnimatedGradientVisual::AnimationParameter Property + */ + enum Property + { + + /** + * @brief The start value of this animation. + * @details Name "startValue", type depends on AnimatedGradientVisual Property. + * @note If not supplied, default is Property::Value( 0.0f ). + */ + START = DevelAnimatedGradientVisual::Property::OFFSET + 1, + + /** + * @brief The target value of this animation. + * @details Name "targetValue", type depends on AnimatedGradientVisual Property. + * @note If not supplied, default is Property::Value( 0.0f ). + */ + TARGET, + + /** + * @brief The direction of this animation. + * @details Name "directionType", type DirectionType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is DirectionType::FORWARD. + * @see DirectionType::Type + */ + DIRECTION, + + /** + * @brief The duration of this animation in seconds. + * @details Name "duration", type Property::FLOAT. + * @note If not supplied, default is 3.0f. + */ + DURATION, + + /** + * @brief The delay of this animation in seconds. + * If delay is positive, wait the animation 'delay' seconds. + * If delay is negative, skip the animation '-delay' seconds. + * @details Name "delay", type Property::FLOAT. + * @note If not supplied, default is 0.0f. + */ + DELAY, + + /** + * @brief The repeat count of this animation. + * If repeat is negative, animate unlimited loop. + * If repeat is zero, animation will no run. + * If repeat is positive, animate 'repeat' times. + * @details Name "repeat", type Property::INTEGER. + * @note If not supplied, default is 0. + */ + REPEAT, + + /** + * @brief The delay before each loop of this animation in seconds. + * @details Name "repeatDelay", type Property::FLOAT. + * @note If not supplied, default is 0.0f. + */ + REPEAT_DELAY, + + /** + * @brief The motion of this animation. + * @details Name "motionType", type MotionType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is MotionType::LOOP. + * @see MotionType::Type + */ + MOTION_TYPE, + + /** + * @brief The easing option of this animation. + * @details Name "easingType", type EasingType::Type (Property::INTEGER) or Property::STRING. + * @note If not supplied, default is EasingType::LINEAR. + * @see EasingType::Type + */ + EASING_TYPE + }; + + /** + * @brief The type of animation direction + */ + namespace DirectionType + { + + /** + * @brief The type of animation direction + */ + enum Type + { + FORWARD, ///< Animate value from START to TARGET + BACKWARD, ///< Animate value frome TARGET to START + }; + + } // namespace DirectionType + + /** + * @brief The type of animation motion + */ + namespace MotionType + { + + /** + * @brief The type of animation motion + */ + enum Type + { + LOOP, ///< Animate loopingmode restart + MIRROR, ///< Animate loopingmode auto_reverse + }; + + } // namespace MotionType + + /** + * @brief The type of animation easing + */ + namespace EasingType + { + + /** + * @brief The type of animation easing + */ + enum Type + { + LINEAR, ///< Easing animation linear + IN, ///< Ease-in animation (slow start -> fast finish) + OUT, ///< Ease-out animation (fast start -> slow finish) + IN_OUT, ///< Ease-in and Ease-out animation (slow start -> slow finish) + }; + + } // namespace EasingType + + } // namespace AnimationParameter + + } // namespace DevelAnimatedGradientVisual + + /** + * + */ + + } // namespace Toolkit + + } // namespace Dali + + #endif diff --cc dali-toolkit/devel-api/visuals/color-visual-properties-devel.h index 0000000,4eb8b3a..2402d6f mode 000000,100644..100644 --- a/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h @@@ -1,0 -1,68 +1,68 @@@ + #ifndef DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H + #define DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H + + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + // INTERNAL INCLUDES + #include + + namespace Dali + { + + namespace Toolkit + { + + + namespace DevelColorVisual + { + + /** + * @brief Additional ColorVisual Properties. + */ + namespace Property + { + + /** + * @brief Enumeration for the instance of additional properties belonging to the ColorVisual. + */ + enum + { + MIX_COLOR = Toolkit::ColorVisual::Property::MIX_COLOR, + + /** + * @brief Whether to render if the MIX_COLOR is transparent. + * @details Name "renderIfTransparent", type Property::BOOLEAN. + * @note Optional. + * @note By default it's false, i.e. ColorVisual will not render if the MIX_COLOR is transparent. + */ + RENDER_IF_TRANSPARENT = MIX_COLOR + 1, + }; + + } // namespace Property + + } // namespace ColorVisual + + /** + * @} + */ + + } // namespace Toolkit + + } // namespace Dali + + #endif // DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H diff --cc dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp index eb452c0,8880b31..dca16f7 --- a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp +++ b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h index 23da644,69e924a..bfdb6ab --- a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h +++ b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_INTERNAL_ACCESSIBILITY_MANAGER_H__ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/builder/builder-impl.cpp index 5a18bef,e5da81e..f3f856d --- a/dali-toolkit/internal/builder/builder-impl.cpp +++ b/dali-toolkit/internal/builder/builder-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp index 1a1f9f0,c05e954..4520780 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/buttons/button-impl.cpp index 7f91013,84dd7a1..1aa7774 --- a/dali-toolkit/internal/controls/buttons/button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/button-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/flex-container/flex-container-impl.h index c56a3ca,9b8b9e9..0d30cd7 mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/flex-container/flex-container-impl.h +++ b/dali-toolkit/internal/controls/flex-container/flex-container-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_INTERNAL_FLEX_CONTAINER_H__ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp index 45cf8b7,cd8438e..818fd09 --- a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h index 39f9e53,d95d190..10dee51 --- a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp index 31201ee,6cd2e67..2525190 --- a/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2014 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/table-view/table-view-impl.cpp index 703440a,abb9eea..71c6454 mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.cpp +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/table-view/table-view-impl.h index a162b7a,a162b7a..f411b7c mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.h +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_INTERNAL_TABLE_VIEW_H__ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index 8ac3938,80e884a..1645092 mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/text-controls/text-editor-impl.h index f121799,5595e18..63d64ae mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 1417743,d92be64..31b57d6 mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/text-controls/text-field-impl.h index b8f49ee,495f789..ba279fa mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/controls/video-view/video-view-impl.h index cd7102c,bed7c9f..0a05b46 mode 100644,100755..100755 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.h +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_VIDEO_VIEW_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/image-loader/image-load-thread.cpp index 7e0a181,857a55b..84163d9 --- a/dali-toolkit/internal/image-loader/image-load-thread.cpp +++ b/dali-toolkit/internal/image-loader/image-load-thread.cpp @@@ -1,5 -1,5 +1,5 @@@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/image-loader/image-load-thread.h index 3d0ad24,c3f230c..bf8eaac --- a/dali-toolkit/internal/image-loader/image-load-thread.h +++ b/dali-toolkit/internal/image-loader/image-load-thread.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_IMAGE_LOAD_THREAD_H__ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/cursor-helper-functions.cpp index 91b6a40,f437b8d..4f59a47 --- a/dali-toolkit/internal/text/cursor-helper-functions.cpp +++ b/dali-toolkit/internal/text/cursor-helper-functions.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/decorator/text-decorator.cpp index e9e0b1a,be8cdd0..6f35ea3 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/decorator/text-decorator.h index 8cff322,4818a72..aff59c4 --- a/dali-toolkit/internal/text/decorator/text-decorator.h +++ b/dali-toolkit/internal/text/decorator/text-decorator.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEXT_DECORATOR_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/layouts/layout-engine.cpp index 3e633ba,af257ff..0ef559d --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/layouts/layout-parameters.h index 47aed0e,7f3e169..e9b72ab --- a/dali-toolkit/internal/text/layouts/layout-parameters.h +++ b/dali-toolkit/internal/text/layouts/layout-parameters.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/line-run.h index 52df79e,9023121..8b1087a --- a/dali-toolkit/internal/text/line-run.h +++ b/dali-toolkit/internal/text/line-run.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEXT_LINE_RUN_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/markup-processor-helper-functions.cpp index 8af6140,76d9a6a..282b5b8 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/markup-processor-helper-functions.h index 45f586c,d1ecbc8..dd8e1e3 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.h +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_HELPER_FUNCTIONS_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/markup-processor.cpp index 5bbe5ad,25b4616..94d8137 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/multi-language-support-impl.cpp index e88a286,7570e04..b0f72d0 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp index 0d72be9,957fd8e..dd681ac --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h index a2232f9,0d32834..71f3301 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp index 743bc6c,bd6850d..59de66a --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h index 1bc058b,c41415e..c318b2a --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 62865d6,c6d1f80..507ee5f --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/rendering/text-typesetter.h index 285348e,453541b..bfe3722 --- a/dali-toolkit/internal/text/rendering/text-typesetter.h +++ b/dali-toolkit/internal/text/rendering/text-typesetter.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_TEXT_TYPESETTER_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/text-controller-impl.cpp index c1eb0e4,caefc0c..d0d8dd6 mode 100644,100755..100755 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/text-controller-impl.h index 44d1a7d,34601f5..764367b mode 100644,100755..100755 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/text-view-interface.h index efa88ad,96f9005..0147d1d --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/text-view.cpp index 9e8d0be,62c0008..15eee10 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/text/text-view.h index d494d2b,51426de..558eb70 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_TEXT_VIEW_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h index 0000000,ab480d9..2441eab mode 000000,100755..100755 --- a/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h +++ b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h @@@ -1,0 -1,281 +1,281 @@@ + #ifndef DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H + #define DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H + + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + //EXTERNAL INCLUDES + #include + #include + #include + #include + + //INTERNAL INCLUDES + #include + #include + #include + + namespace Dali + { + + namespace Toolkit + { + + namespace Internal + { + class AnimatedGradientVisual; + typedef IntrusivePtr< AnimatedGradientVisual > AnimatedGradientVisualPtr; + + /** + * This visual which renders smooth transition of colors to the control's quad. + * There are two types of properties: non-animated property and animated property + * + * The following properties are non-animated property. + * + * | %Property Name | Type | Default | + * |----------------|--------------|---------------------------| + * | gradientType | GradientType | Linear | + * | unitType | UnitType | Object bounding box | + * | spreadType | SpreadType | Reflect | + * + * The following properties are animated property. + * + * | %Property Name | Type | Default | + * |----------------|------------------------------------------|---------------------------------| + * | startPosition | Vector2 or AnimationParameter< Vector2 > | (-0.5, 0) | + * | startColor | Vector4 or AnimationParameter< Vector4 > | (143., 170., 220., 255.) / 255. | + * | endPosition | Vector2 or AnimationParameter< Vector2 > | (0.5, 0) | + * | endColor | Vector4 or AnimationParameter< Vector4 > | (255., 163., 163., 255.) / 255. | + * | rotateCenter | Vector2 or AnimationParameter< Vector2 > | (0.0, 0.0) | + * | rotateAmount | Float or AnimationParameter< Float > | 0.0 | + * | offset | Float or AnimationParameter< Float > | (explain details below) | + * + * Each animated property can contain follow AnimationParameter + * + * | %AnimationParameter::Propery Name | Type | Default | + * |--------------------------------------|---------------|----------| + * | start | T | Zero | + * | target | T | Zero | + * | direction | DirectionType | Forward | + * | duration | Float | 3.0 | + * | delay | Float | 0.0 | + * | repeat | Integer | 0 | + * | repeat_delay | Float | 0.0 | + * | motion_type | MotionType | Loop | + * | easing_type | EasingType | Linear | + * + * T is animated property value's type. If property type is AnimationParameter< Vector2 >, start and target type is Vector2. + * + * + * gradientType decide the form of gradient + * unitType decide the coordinate of all positions + * spreadType decide how to make color where gradient_point is not 0 ~ 1 + * visualSize decide this visual's size hardly. only use when unitType is SCREEN + * + * startPoint and startColor decide position and color where gradient_point = 0. if gradientType is RADIAL, here is center of circle. + * endPoint and endColor decide position and color where gradient_point = 1. + * rotateCenter and rotateAmount are same job as its name + * rotateAmount is radian value + * + * offset is main feature of this visual. + * Image the points which has same gradient_point values. If gradientType is LINEAR, this form is line. If gradientTYPE IS RADIAL, this form is circle. + * without think about offset value, gradient_point = t color will be like this + * + * color(t) = startColor * (1-t) + endColor * t (0 <= t <= 1) + * + * so color be smooth changed when gradient_point change smooth. + * offset value change the color of gradient_point = t like this + * + * realColor(t) = color(t + offset) + * + * so If offset value increas (or decrease) gradient looks like "Flowing" effect + * default offset value is an unlimited simple loop animation from 0 to 2. duration is 3.0 second + * + * GradientType has two types : LINEAR / RADIAL + * LINEAR draw gradient linear form + * RADIAL draw gradietn circle form + * UnitType has two types : OBJECT_BOUNDING_BOX / USER_SPACE + * OBJECT_BOUNDING_BOX use normalized coordinate, relate by Actor bounding box. bottom-left ~ top-right : (-0.5,-0.5) ~ (0.5, 0.5) + * USER_SPACE use coordinate, relate by Actor Size. bottom-left ~ top-right : (ActorSize * -0.5) ~ (ActorSize * 0.5) + * SpreadType has three types : REFLECT / REPEAT / CLAMP + * REFLECT use mirror warping + * REPEAT use repeat warping + * CLAMP use clamp warping + * + * DirectionType has two types : FORWARD / BACKWARD + * FORWARD animate value from start to target + * BACKWARD animate value from target to start + * MotionType has two types : LOOP / MIRROR + * LOOP animate loopingmode restart + * MIRROR animate loopingmode auto_reverse + * EasingType has four types : LINEAR / IN / OUT / IN_OUT + * LINEAR easing animation linear + * IN easing in (slow start -> fast finish) + * OUT easing out (fast start -> slow finish) + * IN_OUT easing in and out (slow start -> slow finish) + */ + class AnimatedGradientVisual : public Visual::Base + { + public: + + /** + * Animation informations what this visual using + */ + struct GradientAnimationData + { + GradientAnimationData() + : index( Property::INVALID_INDEX ), + loop_count( 0 ), + delay( 0.0f ), + forward( false ), + auto_mirror( false ) + { + } + + Toolkit::TransitionData transition; + Animation animation; + Property::Index index; + int loop_count; ///< if < 0, loop unlimited. else, loop loop_count times. + float delay; ///< delay time. if > 0, wait 'delay' seconds. else, play animation at '-delay' seconds. + bool forward; ///< True if AnimationParameter::DirectionType::Type is FORWARD + bool auto_mirror; ///< True if AnimationParameter::LoopType::Type is MIRROR + }; + + using GradientAnimationDataList = Dali::OwnerContainer< GradientAnimationData* >; + + public: + + /** + * @brief Create a new animated gradient visual. + * + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] properties A Property::Map containing settings for this visual + * @return A smart-pointer to the newly allocated visual + */ + static AnimatedGradientVisualPtr New( VisualFactoryCache& factoryCache, const Property::Map& properties ); + + private: //from Visual + + /** + * @copydoc Visual::Base::CreatePropertyMap + */ + virtual void DoCreatePropertyMap( Property::Map& map ) const; + + /** + * @copydoc Visual::Base::CreateInstancePropertyMap + */ + virtual void DoCreateInstancePropertyMap( Property::Map& map ) const; + + protected: + + /** + * @brief Constructor. + * + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + */ + AnimatedGradientVisual( VisualFactoryCache& factoryCache ); + + /** + * @brief A reference counted object may only be deleted by calling Unrefecence() + */ + virtual ~AnimatedGradientVisual(); + + protected: //from Visual + + /** + * @copydoc Visual::Base::DoSetProperties + */ + virtual void DoSetProperties( const Property::Map& propertyMap ); + + /** + * @copydoc Visual::Base::OnSetTransform + */ + virtual void OnSetTransform(); + + /** + * @copydoc Visual::Base::DoSetOnStage + */ + virtual void DoSetOnStage( Actor& actor ); + + /** + * @copydoc Visual::Base::DoSetOffStage + */ + virtual void DoSetOffStage( Actor& actor ); + + private: + + /** + * @brief Initialize the default value of properies. + */ + void SetupDefaultValue(); + + /** + * @brief Initialize the rendere with the geometry from the cache, and shader which made by CreateShader() + */ + void InitializeRenderer(); + + /** + * @brief Make animations with GradientAnimationData + */ + void SetupAnimation(); + + /** + * @brief Play animations + */ + void PlayAnimation(); + + /** + * @brief Stop animations + */ + void StopAnimation(); + + /** + * @brief Clear all previous GradientAnimationData and Setup new GradientAnimationData information which made by animated properties + * + * param[in] propertyMap A Property::Map come from DoSetProperties + */ + void SetupGradientAnimationData( const Property::Map& propertyMap ); + + /** + * @brief Create new shader + * + * return A Shader which made by non-animated properties + */ + Shader CreateShader(); + + // Undefined + AnimatedGradientVisual( const AnimatedGradientVisual& gradientRenderer ); + + // Undefined + AnimatedGradientVisual& operator=( const AnimatedGradientVisual& gradientRenderer ); + + private: + GradientAnimationDataList mGradientAnimationDataList; + Property::Map mValueMap; + + Dali::Toolkit::DevelAnimatedGradientVisual::GradientType::Type mGradientType; + Dali::Toolkit::DevelAnimatedGradientVisual::UnitType::Type mUnitType; + Dali::Toolkit::DevelAnimatedGradientVisual::SpreadType::Type mSpreadType; + }; + + }//namespace Internal + + }//namespace Toolkit + + }//namespace Dali + + #endif diff --cc dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp index 32f2bc0,dd06d31..070e690 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h index 4c59447,570b2d7..f3f4a6e --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_FIXED_IMAGE_CACHE_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/animated-image/image-cache.cpp index 1d0db6f,78ca796..bc2794b --- a/dali-toolkit/internal/visuals/animated-image/image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/animated-image/image-cache.h index 12e89e9,e8277de..5e8c648 --- a/dali-toolkit/internal/visuals/animated-image/image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp index 0000000,9f9e623..8114e56 mode 000000,100644..100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp @@@ -1,0 -1,187 +1,187 @@@ + /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + // CLASS HEADER + #include "rolling-gif-image-cache.h" + + // EXTERNAL HEADERS + + // INTERNAL HEADERS + #include + #include // For ImageAtlasManagerPtr + #include + + namespace + { + #if defined(DEBUG_ENABLED) + Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE"); + + #define LOG_CACHE \ + { \ + std::ostringstream oss; \ + oss<<"Size:"< pixelDataList; + + // Get the smallest number of frames we need to load + int batchSize = std::min( std::size_t(mBatchSize), mCacheSize - mQueue.Count() ); + DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingGifImageCache::LoadBatch() mFrameIndex:%d batchSize:%d\n", mFrameIndex, batchSize ); + + if( mGifLoading.LoadNextNFrames( mFrameIndex, batchSize, pixelDataList) ) + { + unsigned int pixelDataListCount = pixelDataList.size(); + + for( unsigned int i = 0; i < pixelDataListCount && !mQueue.IsFull(); ++i ) + { + ImageFrame imageFrame; + + // create the texture for uploading the pixel data + Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, + pixelDataList[i].GetPixelFormat(), + pixelDataList[i].GetWidth(), + pixelDataList[i].GetHeight() ); + + texture.Upload( pixelDataList[i] ); + + mImageUrls[ mUrlIndex ].mUrl = Dali::Toolkit::TextureManager::AddTexture(texture); + imageFrame.mFrameNumber = mUrlIndex; + + ++mUrlIndex; + mUrlIndex %= mImageUrls.size(); + + mQueue.PushBack( imageFrame ); + + bool synchronousLoading = false; + bool atlasingStatus = false; + bool loadingStatus = false; + TextureManager::MaskingDataPointer maskInfo = nullptr; + AtlasUploadObserver* atlasObserver = nullptr; + ImageAtlasManagerPtr imageAtlasManager = nullptr; + Vector4 textureRect; + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + + mTextureManager.LoadTexture( + mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, maskInfo, + synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect, + atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, + Dali::WrapMode::Type::DEFAULT, NULL, + atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply ); + } + + mFrameIndex += batchSize; + mFrameIndex %= mFrameCount; + } + + LOG_CACHE; + } + + TextureSet RollingGifImageCache::GetFrontTextureSet() const + { + DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingGifImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[ 0 ].mFrameNumber ); + + TextureManager::TextureId textureId = GetCachedTextureId( 0 ); + return mTextureManager.GetTextureSet( textureId ); + } + + TextureManager::TextureId RollingGifImageCache::GetCachedTextureId( int index ) const + { + return mImageUrls[ mQueue[ index ].mFrameNumber ].mTextureId; + } + + } //namespace Internal + } //namespace Toolkit + } //namespace Dali diff --cc dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index 847e681,bee7234..1f18567 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/color/color-visual.cpp index 3687a28,fdc4835..4496c46 --- a/dali-toolkit/internal/visuals/color/color-visual.cpp +++ b/dali-toolkit/internal/visuals/color/color-visual.cpp @@@ -26,8 -25,7 +26,9 @@@ //INTERNAL INCLUDES #include #include + #include +#include + #include #include #include @@@ -77,11 -75,9 +78,10 @@@ const char* FRAGMENT_SHADER = DALI_COMP \n void main()\n {\n - gl_FragColor = vec4(mixColor, opacity)*uColor;\n + gl_FragColor = vec4(mixColor, 1.0)*uColor;\n }\n ); +#endif } ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties ) diff --cc dali-toolkit/internal/visuals/color/color-visual.h index 939d40e,4b6dca6..c64f78b --- a/dali-toolkit/internal/visuals/color/color-visual.h +++ b/dali-toolkit/internal/visuals/color/color-visual.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_COLOR_VISUAL_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/image/image-visual.h index 729185a,1a9230c..8e09a54 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/npatch-loader.cpp index f23f1ca,8bc050f..045ddef --- a/dali-toolkit/internal/visuals/npatch-loader.cpp +++ b/dali-toolkit/internal/visuals/npatch-loader.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index b05aed8,618c466..c3c8f66 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@@ -417,15 -493,12 +497,18 @@@ Shader NPatchVisual::CreateShader( if( DALI_LIKELY( ( xStretchCount == 1 && yStretchCount == 1 ) || ( xStretchCount == 0 && yStretchCount == 0 ) ) ) { - shader = mFactoryCache.GetShader( VisualFactoryCache::NINE_PATCH_SHADER ); + shader = mFactoryCache.GetShader( shaderType ); if( DALI_UNLIKELY( !shader ) ) { - //shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER ); - shader = Shader::New( VERTEX_SHADER_3X3, fragmentShader ); - // Only cache vanilla 9 patch shaders ++ //shader = Shader::New( VERTEX_SHADER_3X3, fragment_shader ); ++ //@todo Need new shader for FRAGMENT_MASK_SHADER + shader = DevelShader::New( + GraphicsGetBuiltinShader( "SHADER_NPATCH_VISUAL_3X3_SHADER_VERT" ), + GraphicsGetBuiltinShader( "SHADER_NPATCH_VISUAL_SHADER_FRAG" ), + DevelShader::ShaderLanguage::SPIRV_1_0, Property::Map() ); - mFactoryCache.SaveShader( VisualFactoryCache::NINE_PATCH_SHADER, shader ); ++ ++ // Only cache vanilla 9 patch shaders + mFactoryCache.SaveShader( shaderType, shader ); } } else if( xStretchCount > 0 || yStretchCount > 0) diff --cc dali-toolkit/internal/visuals/npatch/npatch-visual.h index 901211d,d10e687..9e577aa --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.h +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_N_PATCH_VISUAL_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/primitive/primitive-visual.h index 677df9d,6b38bd7..e214cc6 --- a/dali-toolkit/internal/visuals/primitive/primitive-visual.h +++ b/dali-toolkit/internal/visuals/primitive/primitive-visual.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_PRIMITIVE_VISUAL_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/text/text-visual.cpp index 0fbd40b,eb2dc04..0b2fbf2 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@@ -18,12 -18,9 +18,13 @@@ // CLASS HEADER #include +// @todo: using generated file in the dali-core!!!! +#include +#include + // EXTERNAL INCLUDES #include + #include #include // INTERNAL HEADER @@@ -156,28 -141,19 +145,20 @@@ const char* FRAGMENT_SHADER_SINGLE_COLO uniform sampler2D sTexture;\n uniform sampler2D sStyle;\n uniform lowp vec4 uTextColorAnimatable;\n - uniform mediump vec4 uAtlasRect;\n uniform lowp vec4 uColor;\n uniform lowp vec3 mixColor;\n - uniform lowp float opacity;\n uniform lowp float preMultipliedAlpha;\n \n - lowp vec4 visualMixColor()\n - {\n - return vec4( mixColor * mix( 1.0, opacity, preMultipliedAlpha ), opacity );\n - }\n - \n void main()\n {\n - mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n - mediump float textTexture = texture2D( sTexture, texCoord ).r;\n - mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n + mediump float textTexture = texture2D( sTexture, vTexCoord ).r;\n + mediump vec4 styleTexture = texture2D( sStyle, vTexCoord );\n // Draw the text as overlay above the style - gl_FragColor = ( uTextColorAnimatable * textTexture + styleTexture * ( 1.0 - textTexture ) ) * uColor * visualMixColor();\n + gl_FragColor = ( uTextColorAnimatable * textTexture + styleTexture * ( 1.0 - uTextColorAnimatable.a * textTexture ) ) * uColor * vec4( mixColor, 1.0 );\n }\n ); +#endif const char* FRAGMENT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n @@@ -202,10 -170,10 +175,10 @@@ textTexture.rgb *= mix( 1.0, textTexture.a, preMultipliedAlpha );\n // Draw the text as overlay above the style - gl_FragColor = ( textTexture + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * visualMixColor();\n + gl_FragColor = ( textTexture + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, 1.0 );\n }\n ); - +/* const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n uniform sampler2D sTexture;\n @@@ -235,10 -195,10 +200,10 @@@ textTexture.rgb = mix( textTexture.rgb, uTextColorAnimatable.rgb, vstep * maskTexture ) * mix( 1.0, textTexture.a, preMultipliedAlpha );\n // Draw the text as overlay above the style - gl_FragColor = textTexture * uColor * visualMixColor();\n + gl_FragColor = textTexture * uColor * vec4( mixColor, 1.0 );\n }\n ); - +*/ const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n uniform sampler2D sTexture;\n diff --cc dali-toolkit/internal/visuals/text/text-visual.h index ef5890e,6fbf8ed..b6eed81 --- a/dali-toolkit/internal/visuals/text/text-visual.h +++ b/dali-toolkit/internal/visuals/text/text-visual.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/texture-manager-impl.h index 7693b1c,e56fec4..9993871 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-factory-cache.cpp index d9a566d,101e696..f8f9f83 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-cache.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-factory-cache.h index 75c949e,a62dfb4..ef6004e --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_VISUAL_FACTORY_CACHE_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-factory-impl.cpp index 826de69,e762b3e..0900f5c --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-factory-impl.h index 257b03c,a9a6563..d680da6 --- a/dali-toolkit/internal/visuals/visual-factory-impl.h +++ b/dali-toolkit/internal/visuals/visual-factory-impl.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_VISUAL_FACTORY_IMPL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-url.cpp index 907b428,b1f5f3e..1c9919d --- a/dali-toolkit/internal/visuals/visual-url.cpp +++ b/dali-toolkit/internal/visuals/visual-url.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/internal/visuals/visual-url.h index b261813,aac605c..2dec75ff --- a/dali-toolkit/internal/visuals/visual-url.h +++ b/dali-toolkit/internal/visuals/visual-url.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_INTERNAL_VISUAL_URL_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/controls/control-impl.cpp index d7df20a,df78b15..8c192a1 mode 100644,100755..100755 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/controls/control.cpp index 5d28b91,14205f9..ce14052 --- a/dali-toolkit/public-api/controls/control.cpp +++ b/dali-toolkit/public-api/controls/control.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/controls/video-view/video-view.cpp index 7a0aa1d,e709a58..1d9b7d0 --- a/dali-toolkit/public-api/controls/video-view/video-view.cpp +++ b/dali-toolkit/public-api/controls/video-view/video-view.cpp @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/text/rendering-backend.h index 97abfb8,00686ed..6c25486 mode 100644,100755..100755 --- a/dali-toolkit/public-api/text/rendering-backend.h +++ b/dali-toolkit/public-api/text/rendering-backend.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_RENDERING_BACKEND_H__ /* -- * Copyright (c) 2015 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/border-visual-properties.h index 84470a9,3b6c99b..eeac8c4 --- a/dali-toolkit/public-api/visuals/border-visual-properties.h +++ b/dali-toolkit/public-api/visuals/border-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_BORDER_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/color-visual-properties.h index fb87e54,5f1aab9..f6ffacc --- a/dali-toolkit/public-api/visuals/color-visual-properties.h +++ b/dali-toolkit/public-api/visuals/color-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/gradient-visual-properties.h index ae895ca,cdfd624..f0ae4dc --- a/dali-toolkit/public-api/visuals/gradient-visual-properties.h +++ b/dali-toolkit/public-api/visuals/gradient-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_GRADIENT_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/image-visual-properties.h index 589a188,0f5d58b..421cfde --- a/dali-toolkit/public-api/visuals/image-visual-properties.h +++ b/dali-toolkit/public-api/visuals/image-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_IMAGE_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/mesh-visual-properties.h index 765fce7,f431207..3b331d7 --- a/dali-toolkit/public-api/visuals/mesh-visual-properties.h +++ b/dali-toolkit/public-api/visuals/mesh-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_MESH_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/primitive-visual-properties.h index 12f56e5,1e3afcf..1c39e01 --- a/dali-toolkit/public-api/visuals/primitive-visual-properties.h +++ b/dali-toolkit/public-api/visuals/primitive-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_PRIMITIVE_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/text-visual-properties.h index 10c4ab7,0eb7fba..24de8a8 --- a/dali-toolkit/public-api/visuals/text-visual-properties.h +++ b/dali-toolkit/public-api/visuals/text-visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/public-api/visuals/visual-properties.h index 54a4350,cb36f29..9ce4833 --- a/dali-toolkit/public-api/visuals/visual-properties.h +++ b/dali-toolkit/public-api/visuals/visual-properties.h @@@ -2,7 -2,7 +2,7 @@@ #define DALI_TOOLKIT_VISUAL_PROPERTIES_H /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --cc dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json index 50f9529,fa8c6f8..685e34a --- a/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * This file is part of Dali Toolkit * diff --cc dali-toolkit/styles/360x360/dali-toolkit-default-theme.json index 0000000,735b0e5..723d0ad mode 000000,100644..100644 --- a/dali-toolkit/styles/360x360/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/360x360/dali-toolkit-default-theme.json @@@ -1,0 -1,385 +1,385 @@@ + /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * This file is part of Dali Toolkit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + //****************************************************************************** + // + // Default Reference style theme for a 480x800 resolution, The values determined by UX design specification. + // This file can be copied to a new folder within the styles/ directory and amended with new default values. + // Can be overriden if StyleManager applies another style sheet. + // + //****************************************************************************** + + { + "config": + { + "alwaysShowFocus":false, + "clearFocusOnEscape":true + }, + "styles": + { + "TextLabel": + { + "pointSize":18, + "enableAutoScroll":false, + "autoScrollLoopCount":2, + "autoScrollGap":50, + "autoScrollSpeed":80 + }, + + "TextLabelFontSize0": + { + "pointSize":8 + }, + "TextLabelFontSize1": + { + "pointSize":10 + }, + "TextLabelFontSize2": + { + "pointSize":15 + }, + "TextLabelFontSize3": + { + "pointSize":19 + }, + "TextLabelFontSize4": + { + "pointSize":25 + }, + "TextField": + { + "pointSize":18, + "primaryCursorColor":[0.0,0.72,0.9,1.0], + "secondaryCursorColor":[0.0,0.72,0.9,1.0], + "cursorWidth":3, + "selectionHighlightColor":[0.75,0.96,1.0,1.0], + "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png", + "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" }, + "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }, + "enableSelection":true + }, + + "TextFieldFontSize0": + { + "pointSize":10 + }, + "TextFieldFontSize1": + { + "pointSize":10 + }, + "TextFieldFontSize2": + { + "pointSize":10 + }, + "TextFieldFontSize3": + { + "pointSize":10 + }, + "TextFieldFontSize4": + { + "pointSize":10 + }, + "TextSelectionPopup": + { + "popupMaxSize":[656,72], + "optionDividerSize":[2,0], + "popupDividerColor":[0.23,0.72,0.8,0.11], + "popupIconColor":[1.0,1.0,1.0,1.0], + "popupPressedColor":[0.24,0.72,0.8,0.11], + "background": { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}selection-popup-background.9.png" + }, + "backgroundBorder": { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}selection-popup-border.9.png", + "mixColor":[0.24,0.72,0.8,1.0] + }, + "popupFadeInDuration":0.25, + "popupFadeOutDuration":0.25 + }, + "TextSelectionPopupButton": + { + "label": + { + "visualType":"TEXT", + "pointSize":8 + }, + "unselectedBackgroundVisual": + { + "visualType": "IMAGE", + "url": "" + }, + "selectedBackgroundVisual": + { + "visualType": "IMAGE", + "url": "" + } + }, + "TextSelectionToolbar": + { + "enableOvershoot":true, + "enableScrollBar":true, + "scrollView": + { + "overshootAnimationSpeed":360.0, + "overshootSize":[720.0,130.0] + } + }, + "TextSelectionScrollBar": + { + "indicatorShowDuration":0.25, + "indicatorHideDuration":0.25, + "indicatorTransientDuration":1.0 + }, + "TextSelectionScrollIndicator": + { + "image": + { + "visualType":"IMAGE", + "url":"{DALI_IMAGE_DIR}text_selection_scroll_indicator.9.png" + }, + "color":[0.0,0.72,0.9,0.7] + }, + "ScrollView": + { + "overshootEffectColor":"B018", + "overshootAnimationSpeed":360.0, + "overshootSize":[720.0,130.0] + }, + "ItemView": + { + "overshootEffectColor":"B018", + "overshootAnimationSpeed":360.0, + "overshootSize":[720.0,130.0] + }, + "ScrollBar": + { + "indicatorShowDuration":0.25, + "indicatorHideDuration":0.25, + "color":[0.0,0.72,0.9,0.7] + }, + "TextEditor": + { + "pointSize":18, + "primaryCursorColor":[0.0,0.72,0.9,1.0], + "secondaryCursorColor":[0.0,0.72,0.9,1.0], + "cursorWidth":3, + "selectionHighlightColor":[0.75,0.96,1.0,1.0], + "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png", + "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" }, + "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }, + "enableScrollBar":true, + "scrollBarShowDuration":0.8, + "scrollBarFadeDuration":0.5, + "enableSelection":true + }, + "Popup": + { + "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png", + "tailUpImage":"{DALI_IMAGE_DIR}popup_tail_up.png", + "tailDownImage":"{DALI_IMAGE_DIR}popup_tail_down.png", + "tailLeftImage":"{DALI_IMAGE_DIR}popup_tail_left.png", + "tailRightImage":"{DALI_IMAGE_DIR}popup_tail_right.png", + "popupBackgroundBorder":[17,17,13,13] + }, + "ConfirmationPopup": + { + "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png", + "tailUpImage":"{DALI_IMAGE_DIR}popup_tail_up.png", + "tailDownImage":"{DALI_IMAGE_DIR}popup_tail_down.png", + "tailLeftImage":"{DALI_IMAGE_DIR}popup_tail_left.png", + "tailRightImage":"{DALI_IMAGE_DIR}popup_tail_right.png", + "popupBackgroundBorder":[17,17,13,13] + }, + "Slider": + { + "showPopup": true, + "showValue": true, + "valuePrecision": 0, + "trackVisual":{ + "url":"{DALI_IMAGE_DIR}slider-skin.9.png", + "size":[27,27] + }, + "progressVisual":{ + "url":"{DALI_IMAGE_DIR}slider-skin-progress.9.png", + "size":[27,27] + }, + "handleVisual":{ + "url":"{DALI_IMAGE_DIR}slider-skin-handle.png", + "size":[72,72] + }, + "popupVisual":"{DALI_IMAGE_DIR}slider-popup.9.png", + "popupArrowVisual":"{DALI_IMAGE_DIR}slider-popup-arrow.9.png", + "disableColor":[0.5, 0.5, 0.5, 1.0], + "popupTextColor":[0.5,0.5,0.5,1.0], + "hitRegion":[0, 72], + "marks":[], + "snapToMarks":false, + "markTolerance":0.05 + }, + "SliderHandleTextLabel": + { + "textColor":[0.8,0.8,1,1] + }, + "ProgressBar": + { + "trackVisual":{ + "visualType":"IMAGE", + "url":"{DALI_IMAGE_DIR}progress-bar-skin-track.9.png" + }, + "progressVisual":{ + "visualType":"IMAGE", + "url":"{DALI_IMAGE_DIR}progress-bar-skin-progress.9.png" + }, + "secondaryProgressVisual":{ + "visualType":"IMAGE", + "url":"{DALI_IMAGE_DIR}progress-bar-skin-secondary-progress.9.png" + }, + "indeterminateVisual":{ + "visualType":"IMAGE", + "pixelArea":[0.0, 0.0, 10.0, 1.0], + "wrapModeU":"REPEAT", + "url":"{DALI_IMAGE_DIR}progress-bar-skin-indeterminate.png" + }, + "indeterminateVisualAnimation": + [ + { + "target":"indeterminateVisual", + "property":"pixelArea", + "initialValue":[0.0, 0.0, 10.0, 1.0], + "targetValue":[-1.0, 0.0, 10.0, 1.0], + "animator": + { + "alphaFunction":"DEFAULT", + "timePeriod": + { + "duration":0.8, + "delay":0 + } + } + } + ], + "labelVisual":{ + "visualType": "TEXT", + "textColor": [ 1.0, 1.0, 1.0, 1.0 ], + "pointSize" : 12.0, // Point size must always be provided to Text Visual + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER" + }, + "progressValue": 0.0, + "secondaryProgressValue":0.0, + "indeterminate": false + }, + "Button": + { + "initialAutoRepeatingDelay":2.0, + "nextAutoRepeatingDelay":0.9 + // Note: Visuals added to Button will be used in all derived buttons unless overridden. + }, + "PushButton": + { + "anchorPoint": [ 0.5, 1.0, 0.5 ], + "parentOrigin": [ 0.5, 1.0, 0,5 ], + "label": + { + "visualType": "TEXT", + "text" : "BOTTOM_BTN", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "pointSize" : 6.0, + "textColor": [0.98,0.98,0.98,1.0] + }, + "background": + { + "visualType": "IMAGE", + "url": "{DALI_STYLE_IMAGE_DIR}tw_bottom_btn_bg.png", + "mixColor": [0.0,0.21,0.29,0.9] + }, + "selectedStateImage": + { + "visualType": "IMAGE", + "url": "{DALI_STYLE_IMAGE_DIR}tw_bottom_btn_bg.png", + "mixColor": [0.0,0.57,0.8,0.3] + } + }, + "CheckBoxButton": + { + "styles":["Button"], + "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ], + "label": + { + "visualType": "TEXT", + "pointSize" : 10.0, // Point size must always be provided to Text Visual + "verticalAlignment": "CENTER" + }, + "unselectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}checkbox-unselected.png" + }, + "selectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}checkbox-selected.png" + }, + "disabledUnselectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}checkbox-unselected-disabled.png" + }, + "disabledSelectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}checkbox-selected-disabled.png" + } + }, + "RadioButton": + { + "styles":["Button"], + "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ], + "label": + { + "visualType": "TEXT", + "pointSize" : 10.0, // Point size must always be provided to Text Visual + "verticalAlignment": "CENTER" + }, + "unselectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}radio-button-unselected.png" + }, + "selectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}radio-button-selected.png" + }, + "disabledUnselectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}radio-button-unselected-disabled.png" + }, + "disabledSelectedVisual": + { + "visualType": "IMAGE", + "url": "{DALI_IMAGE_DIR}radio-button-selected-disabled.png" + } + } + } + } diff --cc dali-toolkit/styles/480x800/dali-toolkit-default-theme.json index 460d0f8,f35f988..02a1761 --- a/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * This file is part of Dali Toolkit * diff --cc dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json index 9390546,1a9d7ab..dc3f182 --- a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2017 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * This file is part of Dali Toolkit * diff --cc dali-toolkit/third-party/nanosvg/nanosvg.cc index d3ffc40,603f977..8c1fc77 --- a/dali-toolkit/third-party/nanosvg/nanosvg.cc +++ b/dali-toolkit/third-party/nanosvg/nanosvg.cc @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2013-14 Mikko Mononen memon@inside.org ++ * Copyright (c) 2018-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --cc dali-toolkit/third-party/nanosvg/nanosvg.h index 2634297,0e2bad8..40660b4 --- a/dali-toolkit/third-party/nanosvg/nanosvg.h +++ b/dali-toolkit/third-party/nanosvg/nanosvg.h @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2013-14 Mikko Mononen memon@inside.org ++ * Copyright (c) 2018-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --cc dali-toolkit/third-party/nanosvg/nanosvgrast.cc index a3f3bdb,f0bff2e..212c098 --- a/dali-toolkit/third-party/nanosvg/nanosvgrast.cc +++ b/dali-toolkit/third-party/nanosvg/nanosvgrast.cc @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2013-14 Mikko Mononen memon@inside.org ++ * Copyright (c) 2018-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --cc dali-toolkit/third-party/nanosvg/nanosvgrast.h index 3b52600,92f31ea..bad9290 --- a/dali-toolkit/third-party/nanosvg/nanosvgrast.h +++ b/dali-toolkit/third-party/nanosvg/nanosvgrast.h @@@ -1,5 -1,5 +1,5 @@@ /* -- * Copyright (c) 2013-14 Mikko Mononen memon@inside.org ++ * Copyright (c) 2018-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --cc dali-toolkit/third-party/yoga/Utils.cpp index 0000000,6fa8df8..0c59b73 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/Utils.cpp +++ b/dali-toolkit/third-party/yoga/Utils.cpp @@@ -1,0 -1,68 +1,68 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "Utils.h" + + YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction) { + return YGFlexDirectionIsColumn(flexDirection) + ? YGResolveFlexDirection(YGFlexDirectionRow, direction) + : YGFlexDirectionColumn; + } + + float YGFloatMax(const float a, const float b) { + if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + return fmaxf(a, b); + } + return YGFloatIsUndefined(a) ? b : a; + } + + float YGFloatMin(const float a, const float b) { + if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + return fminf(a, b); + } + + return YGFloatIsUndefined(a) ? b : a; + } + + bool YGValueEqual(const YGValue a, const YGValue b) { + if (a.unit != b.unit) { + return false; + } + + if (a.unit == YGUnitUndefined || + (YGFloatIsUndefined(a.value) && YGFloatIsUndefined(b.value))) { + return true; + } + + return fabs(a.value - b.value) < 0.0001f; + } + + bool YGFloatsEqual(const float a, const float b) { + if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + return fabs(a - b) < 0.0001f; + } + return YGFloatIsUndefined(a) && YGFloatIsUndefined(b); + } + + float YGFloatSanitize(const float& val) { + return YGFloatIsUndefined(val) ? 0 : val; + } + + float YGUnwrapFloatOptional(const YGFloatOptional& op) { + return op.isUndefined() ? YGUndefined : op.getValue(); + } + + YGFloatOptional YGFloatOptionalMax( + const YGFloatOptional& op1, + const YGFloatOptional& op2) { + if (!op1.isUndefined() && !op2.isUndefined()) { + return op1.getValue() > op2.getValue() ? op1 : op2; + } + return op1.isUndefined() ? op2 : op1; + } diff --cc dali-toolkit/third-party/yoga/Utils.h index 0000000,6c95b1e..ffdc601 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/Utils.h +++ b/dali-toolkit/third-party/yoga/Utils.h @@@ -1,0 -1,148 +1,148 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include "YGNode.h" + #include "Yoga-internal.h" + + // This struct is an helper model to hold the data for step 4 of flexbox + // algo, which is collecting the flex items in a line. + // + // - itemsOnLine: Number of items which can fit in a line considering the + // available Inner dimension, the flex items computed flexbasis and their + // margin. It may be different than the difference between start and end + // indicates because we skip over absolute-positioned items. + // + // - sizeConsumedOnCurrentLine: It is accumulation of the dimensions and margin + // of all the children on the current line. This will be used in order to either + // set the dimensions of the node if none already exist or to compute the + // remaining space left for the flexible children. + // + // - totalFlexGrowFactors: total flex grow factors of flex items which are to be + // layed in the current line + // + // - totalFlexShrinkFactors: total flex shrink factors of flex items which are + // to be layed in the current line + // + // - endOfLineIndex: Its the end index of the last flex item which was examined + // and it may or may not be part of the current line(as it may be absolutely + // positioned or inculding it may have caused to overshoot availableInnerDim) + // + // - relativeChildren: Maintain a vector of the child nodes that can shrink + // and/or grow. + + struct YGCollectFlexItemsRowValues { + uint32_t itemsOnLine; + float sizeConsumedOnCurrentLine; + float totalFlexGrowFactors; + float totalFlexShrinkScaledFactors; + uint32_t endOfLineIndex; + std::vector relativeChildren; + float remainingFreeSpace; + // The size of the mainDim for the row after considering size, padding, margin + // and border of flex items. This is used to calculate maxLineDim after going + // through all the rows to decide on the main axis size of owner. + float mainDim; + // The size of the crossDim for the row after considering size, padding, + // margin and border of flex items. Used for calculating containers crossSize. + float crossDim; + }; + + bool YGValueEqual(const YGValue a, const YGValue b); + + // This custom float equality function returns true if either absolute + // difference between two floats is less than 0.0001f or both are undefined. + bool YGFloatsEqual(const float a, const float b); + + // We need custom max function, since we want that, if one argument is + // YGUndefined then the max funtion should return the other argument as the max + // value. We wouldn't have needed a custom max function if YGUndefined was NAN + // as fmax has the same behaviour, but with NAN we cannot use `-ffast-math` + // compiler flag. + float YGFloatMax(const float a, const float b); + + YGFloatOptional YGFloatOptionalMax( + const YGFloatOptional& op1, + const YGFloatOptional& op2); + + // We need custom min function, since we want that, if one argument is + // YGUndefined then the min funtion should return the other argument as the min + // value. We wouldn't have needed a custom min function if YGUndefined was NAN + // as fmin has the same behaviour, but with NAN we cannot use `-ffast-math` + // compiler flag. + float YGFloatMin(const float a, const float b); + + // This custom float comparision function compares the array of float with + // YGFloatsEqual, as the default float comparision operator will not work(Look + // at the comments of YGFloatsEqual function). + template + bool YGFloatArrayEqual( + const std::array& val1, + const std::array& val2) { + bool areEqual = true; + for (std::size_t i = 0; i < size && areEqual; ++i) { + areEqual = YGFloatsEqual(val1[i], val2[i]); + } + return areEqual; + } + + // This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise + float YGFloatSanitize(const float& val); + + // This function unwraps optional and returns YGUndefined if not defined or + // op.value otherwise + // TODO: Get rid off this function + float YGUnwrapFloatOptional(const YGFloatOptional& op); + + YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction); + + inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionRow || + flexDirection == YGFlexDirectionRowReverse; + } + + inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) { + switch (value.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return YGFloatOptional(); + case YGUnitPoint: + return YGFloatOptional(value.value); + case YGUnitPercent: + return YGFloatOptional( + static_cast(value.value * ownerSize * 0.01)); + } + return YGFloatOptional(); + } + + inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionColumn || + flexDirection == YGFlexDirectionColumnReverse; + } + + inline YGFlexDirection YGResolveFlexDirection( + const YGFlexDirection flexDirection, + const YGDirection direction) { + if (direction == YGDirectionRTL) { + if (flexDirection == YGFlexDirectionRow) { + return YGFlexDirectionRowReverse; + } else if (flexDirection == YGFlexDirectionRowReverse) { + return YGFlexDirectionRow; + } + } + + return flexDirection; + } + + static inline YGFloatOptional YGResolveValueMargin( + const YGValue value, + const float ownerSize) { + return value.unit == YGUnitAuto ? YGFloatOptional(0) + : YGResolveValue(value, ownerSize); + } diff --cc dali-toolkit/third-party/yoga/YGConfig.cpp index 0000000,5cee527..91e939a mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGConfig.cpp +++ b/dali-toolkit/third-party/yoga/YGConfig.cpp @@@ -1,0 -1,19 +1,19 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGConfig.h" + + const std::array + kYGDefaultExperimentalFeatures = {{false}}; + + YGConfig::YGConfig(YGLogger logger) + : experimentalFeatures(kYGDefaultExperimentalFeatures), + useWebDefaults(false), + useLegacyStretchBehaviour(false), + shouldDiffLayoutWithoutLegacyStretchBehaviour(false), + pointScaleFactor(1.0f), logger(logger), cloneNodeCallback(nullptr), + context(nullptr) {} diff --cc dali-toolkit/third-party/yoga/YGConfig.h index 0000000,0f655d1..3152449 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGConfig.h +++ b/dali-toolkit/third-party/yoga/YGConfig.h @@@ -1,0 -1,23 +1,23 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include "Yoga-internal.h" + #include "Yoga.h" + + struct YGConfig { + std::array experimentalFeatures; + bool useWebDefaults; + bool useLegacyStretchBehaviour; + bool shouldDiffLayoutWithoutLegacyStretchBehaviour; + float pointScaleFactor; + YGLogger logger; + YGCloneNodeFunc cloneNodeCallback; + void* context; + + YGConfig(YGLogger logger); + }; diff --cc dali-toolkit/third-party/yoga/YGEnums.cpp index 0000000,7f16628..97ee15f mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGEnums.cpp +++ b/dali-toolkit/third-party/yoga/YGEnums.cpp @@@ -1,0 -1,226 +1,226 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGEnums.h" + + const char *YGAlignToString(const YGAlign value){ + switch(value){ + case YGAlignAuto: + return "auto"; + case YGAlignFlexStart: + return "flex-start"; + case YGAlignCenter: + return "center"; + case YGAlignFlexEnd: + return "flex-end"; + case YGAlignStretch: + return "stretch"; + case YGAlignBaseline: + return "baseline"; + case YGAlignSpaceBetween: + return "space-between"; + case YGAlignSpaceAround: + return "space-around"; + } + return "unknown"; + } + + const char *YGDimensionToString(const YGDimension value){ + switch(value){ + case YGDimensionWidth: + return "width"; + case YGDimensionHeight: + return "height"; + } + return "unknown"; + } + + const char *YGDirectionToString(const YGDirection value){ + switch(value){ + case YGDirectionInherit: + return "inherit"; + case YGDirectionLTR: + return "ltr"; + case YGDirectionRTL: + return "rtl"; + } + return "unknown"; + } + + const char *YGDisplayToString(const YGDisplay value){ + switch(value){ + case YGDisplayFlex: + return "flex"; + case YGDisplayNone: + return "none"; + } + return "unknown"; + } + + const char *YGEdgeToString(const YGEdge value){ + switch(value){ + case YGEdgeLeft: + return "left"; + case YGEdgeTop: + return "top"; + case YGEdgeRight: + return "right"; + case YGEdgeBottom: + return "bottom"; + case YGEdgeStart: + return "start"; + case YGEdgeEnd: + return "end"; + case YGEdgeHorizontal: + return "horizontal"; + case YGEdgeVertical: + return "vertical"; + case YGEdgeAll: + return "all"; + } + return "unknown"; + } + + const char *YGExperimentalFeatureToString(const YGExperimentalFeature value){ + switch(value){ + case YGExperimentalFeatureWebFlexBasis: + return "web-flex-basis"; + } + return "unknown"; + } + + const char *YGFlexDirectionToString(const YGFlexDirection value){ + switch(value){ + case YGFlexDirectionColumn: + return "column"; + case YGFlexDirectionColumnReverse: + return "column-reverse"; + case YGFlexDirectionRow: + return "row"; + case YGFlexDirectionRowReverse: + return "row-reverse"; + } + return "unknown"; + } + + const char *YGJustifyToString(const YGJustify value){ + switch(value){ + case YGJustifyFlexStart: + return "flex-start"; + case YGJustifyCenter: + return "center"; + case YGJustifyFlexEnd: + return "flex-end"; + case YGJustifySpaceBetween: + return "space-between"; + case YGJustifySpaceAround: + return "space-around"; + case YGJustifySpaceEvenly: + return "space-evenly"; + } + return "unknown"; + } + + const char *YGLogLevelToString(const YGLogLevel value){ + switch(value){ + case YGLogLevelError: + return "error"; + case YGLogLevelWarn: + return "warn"; + case YGLogLevelInfo: + return "info"; + case YGLogLevelDebug: + return "debug"; + case YGLogLevelVerbose: + return "verbose"; + case YGLogLevelFatal: + return "fatal"; + } + return "unknown"; + } + + const char *YGMeasureModeToString(const YGMeasureMode value){ + switch(value){ + case YGMeasureModeUndefined: + return "undefined"; + case YGMeasureModeExactly: + return "exactly"; + case YGMeasureModeAtMost: + return "at-most"; + } + return "unknown"; + } + + const char *YGNodeTypeToString(const YGNodeType value){ + switch(value){ + case YGNodeTypeDefault: + return "default"; + case YGNodeTypeText: + return "text"; + } + return "unknown"; + } + + const char *YGOverflowToString(const YGOverflow value){ + switch(value){ + case YGOverflowVisible: + return "visible"; + case YGOverflowHidden: + return "hidden"; + case YGOverflowScroll: + return "scroll"; + } + return "unknown"; + } + + const char *YGPositionTypeToString(const YGPositionType value){ + switch(value){ + case YGPositionTypeRelative: + return "relative"; + case YGPositionTypeAbsolute: + return "absolute"; + } + return "unknown"; + } + + const char *YGPrintOptionsToString(const YGPrintOptions value){ + switch(value){ + case YGPrintOptionsLayout: + return "layout"; + case YGPrintOptionsStyle: + return "style"; + case YGPrintOptionsChildren: + return "children"; + } + return "unknown"; + } + + const char *YGUnitToString(const YGUnit value){ + switch(value){ + case YGUnitUndefined: + return "undefined"; + case YGUnitPoint: + return "point"; + case YGUnitPercent: + return "percent"; + case YGUnitAuto: + return "auto"; + } + return "unknown"; + } + + const char *YGWrapToString(const YGWrap value){ + switch(value){ + case YGWrapNoWrap: + return "no-wrap"; + case YGWrapWrap: + return "wrap"; + case YGWrapWrapReverse: + return "wrap-reverse"; + } + return "unknown"; + } diff --cc dali-toolkit/third-party/yoga/YGEnums.h index 0000000,0976d78..5bcf14c mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGEnums.h +++ b/dali-toolkit/third-party/yoga/YGEnums.h @@@ -1,0 -1,155 +1,155 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + + #include "YGMacros.h" + + YG_EXTERN_C_BEGIN + + #define YGAlignCount 8 + typedef YG_ENUM_BEGIN(YGAlign) { + YGAlignAuto, + YGAlignFlexStart, + YGAlignCenter, + YGAlignFlexEnd, + YGAlignStretch, + YGAlignBaseline, + YGAlignSpaceBetween, + YGAlignSpaceAround, + } YG_ENUM_END(YGAlign); + WIN_EXPORT const char *YGAlignToString(const YGAlign value); + + #define YGDimensionCount 2 + typedef YG_ENUM_BEGIN(YGDimension) { + YGDimensionWidth, + YGDimensionHeight, + } YG_ENUM_END(YGDimension); + WIN_EXPORT const char *YGDimensionToString(const YGDimension value); + + #define YGDirectionCount 3 + typedef YG_ENUM_BEGIN(YGDirection) { + YGDirectionInherit, + YGDirectionLTR, + YGDirectionRTL, + } YG_ENUM_END(YGDirection); + WIN_EXPORT const char *YGDirectionToString(const YGDirection value); + + #define YGDisplayCount 2 + typedef YG_ENUM_BEGIN(YGDisplay) { + YGDisplayFlex, + YGDisplayNone, + } YG_ENUM_END(YGDisplay); + WIN_EXPORT const char *YGDisplayToString(const YGDisplay value); + + #define YGEdgeCount 9 + typedef YG_ENUM_BEGIN(YGEdge) { + YGEdgeLeft, + YGEdgeTop, + YGEdgeRight, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeHorizontal, + YGEdgeVertical, + YGEdgeAll, + } YG_ENUM_END(YGEdge); + WIN_EXPORT const char *YGEdgeToString(const YGEdge value); + + #define YGExperimentalFeatureCount 1 + typedef YG_ENUM_BEGIN(YGExperimentalFeature) { + YGExperimentalFeatureWebFlexBasis, + } YG_ENUM_END(YGExperimentalFeature); + WIN_EXPORT const char *YGExperimentalFeatureToString(const YGExperimentalFeature value); + + #define YGFlexDirectionCount 4 + typedef YG_ENUM_BEGIN(YGFlexDirection) { + YGFlexDirectionColumn, + YGFlexDirectionColumnReverse, + YGFlexDirectionRow, + YGFlexDirectionRowReverse, + } YG_ENUM_END(YGFlexDirection); + WIN_EXPORT const char *YGFlexDirectionToString(const YGFlexDirection value); + + #define YGJustifyCount 6 + typedef YG_ENUM_BEGIN(YGJustify){ + YGJustifyFlexStart, + YGJustifyCenter, + YGJustifyFlexEnd, + YGJustifySpaceBetween, + YGJustifySpaceAround, + YGJustifySpaceEvenly, + } YG_ENUM_END(YGJustify); + WIN_EXPORT const char *YGJustifyToString(const YGJustify value); + + #define YGLogLevelCount 6 + typedef YG_ENUM_BEGIN(YGLogLevel) { + YGLogLevelError, + YGLogLevelWarn, + YGLogLevelInfo, + YGLogLevelDebug, + YGLogLevelVerbose, + YGLogLevelFatal, + } YG_ENUM_END(YGLogLevel); + WIN_EXPORT const char *YGLogLevelToString(const YGLogLevel value); + + #define YGMeasureModeCount 3 + typedef YG_ENUM_BEGIN(YGMeasureMode) { + YGMeasureModeUndefined, + YGMeasureModeExactly, + YGMeasureModeAtMost, + } YG_ENUM_END(YGMeasureMode); + WIN_EXPORT const char *YGMeasureModeToString(const YGMeasureMode value); + + #define YGNodeTypeCount 2 + typedef YG_ENUM_BEGIN(YGNodeType) { + YGNodeTypeDefault, + YGNodeTypeText, + } YG_ENUM_END(YGNodeType); + WIN_EXPORT const char *YGNodeTypeToString(const YGNodeType value); + + #define YGOverflowCount 3 + typedef YG_ENUM_BEGIN(YGOverflow) { + YGOverflowVisible, + YGOverflowHidden, + YGOverflowScroll, + } YG_ENUM_END(YGOverflow); + WIN_EXPORT const char *YGOverflowToString(const YGOverflow value); + + #define YGPositionTypeCount 2 + typedef YG_ENUM_BEGIN(YGPositionType) { + YGPositionTypeRelative, + YGPositionTypeAbsolute, + } YG_ENUM_END(YGPositionType); + WIN_EXPORT const char *YGPositionTypeToString(const YGPositionType value); + + #define YGPrintOptionsCount 3 + typedef YG_ENUM_BEGIN(YGPrintOptions) { + YGPrintOptionsLayout = 1, + YGPrintOptionsStyle = 2, + YGPrintOptionsChildren = 4, + } YG_ENUM_END(YGPrintOptions); + WIN_EXPORT const char *YGPrintOptionsToString(const YGPrintOptions value); + + #define YGUnitCount 4 + typedef YG_ENUM_BEGIN(YGUnit) { + YGUnitUndefined, + YGUnitPoint, + YGUnitPercent, + YGUnitAuto, + } YG_ENUM_END(YGUnit); + WIN_EXPORT const char *YGUnitToString(const YGUnit value); + + #define YGWrapCount 3 + typedef YG_ENUM_BEGIN(YGWrap) { + YGWrapNoWrap, + YGWrapWrap, + YGWrapWrapReverse, + } YG_ENUM_END(YGWrap); + WIN_EXPORT const char *YGWrapToString(const YGWrap value); + + YG_EXTERN_C_END diff --cc dali-toolkit/third-party/yoga/YGFloatOptional.cpp index 0000000,00bfc71..79f391d mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGFloatOptional.cpp +++ b/dali-toolkit/third-party/yoga/YGFloatOptional.cpp @@@ -1,0 -1,92 +1,92 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGFloatOptional.h" + #include + #include + #include "Yoga.h" + + YGFloatOptional::YGFloatOptional(const float& value) { + if (YGFloatIsUndefined(value)) { + isUndefined_ = true; + value_ = 0; + } else { + value_ = value; + isUndefined_ = false; + } + } + + YGFloatOptional::YGFloatOptional() : value_(0), isUndefined_(true) {} + + const float& YGFloatOptional::getValue() const { + if (isUndefined_) { + // Abort, accessing a value of an undefined float optional + std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; + std::exit(EXIT_FAILURE); + } + return value_; + } + + void YGFloatOptional::setValue(const float& val) { + value_ = val; + isUndefined_ = false; + } + + const bool& YGFloatOptional::isUndefined() const { + return isUndefined_; + } + + bool YGFloatOptional::operator==(const YGFloatOptional& op) const { + if (isUndefined_ == op.isUndefined()) { + return isUndefined_ ? true : value_ == op.getValue(); + } + return false; + } + + bool YGFloatOptional::operator!=(const YGFloatOptional& op) const { + return !(*this == op); + } + + bool YGFloatOptional::operator==(const float& val) const { + if (YGFloatIsUndefined(val) == isUndefined_) { + return isUndefined_ ? true : val == value_; + } + return false; + } + + bool YGFloatOptional::operator!=(const float& val) const { + return !(*this == val); + } + + YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) { + if (!isUndefined_ && !op.isUndefined_) { + return YGFloatOptional(value_ + op.value_); + } + return YGFloatOptional(); + } + + bool YGFloatOptional::operator>(const YGFloatOptional& op) const { + if (isUndefined_ || op.isUndefined_) { + return false; + } + return value_ > op.value_; + } + + bool YGFloatOptional::operator<(const YGFloatOptional& op) const { + if (isUndefined_ || op.isUndefined_) { + return false; + } + return value_ < op.value_; + } + + bool YGFloatOptional::operator>=(const YGFloatOptional& op) const { + return *this == op ? true : *this > op; + } + + bool YGFloatOptional::operator<=(const YGFloatOptional& op) const { + return *this == op ? true : *this < op; + } diff --cc dali-toolkit/third-party/yoga/YGFloatOptional.h index 0000000,21af2a8..6ead322 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGFloatOptional.h +++ b/dali-toolkit/third-party/yoga/YGFloatOptional.h @@@ -1,0 -1,39 +1,39 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + + struct YGFloatOptional { + private: + float value_; + bool isUndefined_; + + public: + explicit YGFloatOptional(const float& value); + explicit YGFloatOptional(); + + // Program will terminate if the value of an undefined is accessed. Please + // make sure to check if the optional is defined before calling this function. + // To check if float optional is defined, use `isUndefined()`. + const float& getValue() const; + + // Sets the value of float optional, and thus isUndefined is assigned false. + void setValue(const float& val); + + const bool& isUndefined() const; + + YGFloatOptional operator+(const YGFloatOptional& op); + bool operator>(const YGFloatOptional& op) const; + bool operator<(const YGFloatOptional& op) const; + bool operator>=(const YGFloatOptional& op) const; + bool operator<=(const YGFloatOptional& op) const; + bool operator==(const YGFloatOptional& op) const; + bool operator!=(const YGFloatOptional& op) const; + + bool operator==(const float& val) const; + bool operator!=(const float& val) const; + }; diff --cc dali-toolkit/third-party/yoga/YGLayout.cpp index 0000000,86eaff5..33bcdeb mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGLayout.cpp +++ b/dali-toolkit/third-party/yoga/YGLayout.cpp @@@ -1,0 -1,65 +1,65 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGLayout.h" + #include "Utils.h" + + const std::array kYGDefaultDimensionValues = { + {YGUndefined, YGUndefined}}; + + YGLayout::YGLayout() + : position(), + dimensions(kYGDefaultDimensionValues), + margin(), + border(), + padding(), + direction(YGDirectionInherit), + computedFlexBasisGeneration(0), + computedFlexBasis(YGFloatOptional()), + hadOverflow(false), + generationCount(0), + lastOwnerDirection((YGDirection)-1), + nextCachedMeasurementsIndex(0), + cachedMeasurements(), + measuredDimensions(kYGDefaultDimensionValues), + cachedLayout(YGCachedMeasurement()), + didUseLegacyFlag(false), + doesLegacyStretchFlagAffectsLayout(false) {} + + bool YGLayout::operator==(const YGLayout& layout) const { + bool isEqual = YGFloatArrayEqual(position, layout.position) && + YGFloatArrayEqual(dimensions, layout.dimensions) && + YGFloatArrayEqual(margin, layout.margin) && + YGFloatArrayEqual(border, layout.border) && + YGFloatArrayEqual(padding, layout.padding) && + direction == layout.direction && hadOverflow == layout.hadOverflow && + lastOwnerDirection == layout.lastOwnerDirection && + nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex && + cachedLayout == layout.cachedLayout && + computedFlexBasis == layout.computedFlexBasis; + + for (uint32_t i = 0; i < YG_MAX_CACHED_RESULT_COUNT && isEqual; ++i) { + isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i]; + } + + if (!YGFloatIsUndefined(measuredDimensions[0]) || + !YGFloatIsUndefined(layout.measuredDimensions[0])) { + isEqual = + isEqual && (measuredDimensions[0] == layout.measuredDimensions[0]); + } + if (!YGFloatIsUndefined(measuredDimensions[1]) || + !YGFloatIsUndefined(layout.measuredDimensions[1])) { + isEqual = + isEqual && (measuredDimensions[1] == layout.measuredDimensions[1]); + } + + return isEqual; + } + + bool YGLayout::operator!=(const YGLayout& layout) const { + return !(*this == layout); + } diff --cc dali-toolkit/third-party/yoga/YGLayout.h index 0000000,a820746..0742716 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGLayout.h +++ b/dali-toolkit/third-party/yoga/YGLayout.h @@@ -1,0 -1,42 +1,42 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include "YGFloatOptional.h" + #include "Yoga-internal.h" + + struct YGLayout { + std::array position; + std::array dimensions; + std::array margin; + std::array border; + std::array padding; + YGDirection direction; + + uint32_t computedFlexBasisGeneration; + YGFloatOptional computedFlexBasis; + bool hadOverflow; + + // Instead of recomputing the entire layout every single time, we + // cache some information to break early when nothing changed + uint32_t generationCount; + YGDirection lastOwnerDirection; + + uint32_t nextCachedMeasurementsIndex; + std::array + cachedMeasurements; + std::array measuredDimensions; + + YGCachedMeasurement cachedLayout; + bool didUseLegacyFlag; + bool doesLegacyStretchFlagAffectsLayout; + + YGLayout(); + + bool operator==(const YGLayout& layout) const; + bool operator!=(const YGLayout& layout) const; + }; diff --cc dali-toolkit/third-party/yoga/YGMacros.h index 0000000,15ed81d..7357d4d mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGMacros.h +++ b/dali-toolkit/third-party/yoga/YGMacros.h @@@ -1,0 -1,41 +1,41 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + + #ifdef __cplusplus + #define YG_EXTERN_C_BEGIN extern "C" { + #define YG_EXTERN_C_END } + #else + #define YG_EXTERN_C_BEGIN + #define YG_EXTERN_C_END + #endif + + #ifdef _WINDLL + #define WIN_EXPORT __declspec(dllexport) + #else + #define WIN_EXPORT + #endif + + #ifdef WINARMDLL + #define WIN_STRUCT(type) type * + #define WIN_STRUCT_REF(value) &value + #else + #define WIN_STRUCT(type) type + #define WIN_STRUCT_REF(value) value + #endif + + #ifdef NS_ENUM + // Cannot use NSInteger as NSInteger has a different size than int (which is the default type of a + // enum). + // Therefor when linking the Yoga C library into obj-c the header is a missmatch for the Yoga ABI. + #define YG_ENUM_BEGIN(name) NS_ENUM(int, name) + #define YG_ENUM_END(name) + #else + #define YG_ENUM_BEGIN(name) enum name + #define YG_ENUM_END(name) name + #endif diff --cc dali-toolkit/third-party/yoga/YGNode.cpp index 0000000,6ebc69c..4b2e799 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGNode.cpp +++ b/dali-toolkit/third-party/yoga/YGNode.cpp @@@ -1,0 -1,768 +1,768 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGNode.h" + #include + #include "Utils.h" + + void* YGNode::getContext() const { + return context_; + } + + YGPrintFunc YGNode::getPrintFunc() const { + return print_; + } + + bool YGNode::getHasNewLayout() const { + return hasNewLayout_; + } + + YGNodeType YGNode::getNodeType() const { + return nodeType_; + } + + YGMeasureFunc YGNode::getMeasure() const { + return measure_; + } + + YGBaselineFunc YGNode::getBaseline() const { + return baseline_; + } + + YGDirtiedFunc YGNode::getDirtied() const { + return dirtied_; + } + + YGStyle& YGNode::getStyle() { + return style_; + } + + YGLayout& YGNode::getLayout() { + return layout_; + } + + uint32_t YGNode::getLineIndex() const { + return lineIndex_; + } + + YGNodeRef YGNode::getOwner() const { + return owner_; + } + + YGVector YGNode::getChildren() const { + return children_; + } + + uint32_t YGNode::getChildrenCount() const { + return static_cast(children_.size()); + } + + YGNodeRef YGNode::getChild(uint32_t index) const { + return children_.at(index); + } + + YGNodeRef YGNode::getNextChild() const { + return nextChild_; + } + + YGConfigRef YGNode::getConfig() const { + return config_; + } + + bool YGNode::isDirty() const { + return isDirty_; + } + + YGValue YGNode::getResolvedDimension(int index) { + return resolvedDimensions_[index]; + } + + std::array YGNode::getResolvedDimensions() const { + return resolvedDimensions_; + } + + YGFloatOptional YGNode::getLeadingPosition( + const YGFlexDirection& axis, + const float& axisSize) const { + if (YGFlexDirectionIsRow(axis)) { + const YGValue* leadingPosition = + YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined); + if (leadingPosition->unit != YGUnitUndefined) { + return YGResolveValue(*leadingPosition, axisSize); + } + } + + const YGValue* leadingPosition = + YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined); + + return leadingPosition->unit == YGUnitUndefined + ? YGFloatOptional(0) + : YGResolveValue(*leadingPosition, axisSize); + } + + YGFloatOptional YGNode::getTrailingPosition( + const YGFlexDirection& axis, + const float& axisSize) const { + if (YGFlexDirectionIsRow(axis)) { + const YGValue* trailingPosition = + YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined); + if (trailingPosition->unit != YGUnitUndefined) { + return YGResolveValue(*trailingPosition, axisSize); + } + } + + const YGValue* trailingPosition = + YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined); + + return trailingPosition->unit == YGUnitUndefined + ? YGFloatOptional(0) + : YGResolveValue(*trailingPosition, axisSize); + } + + bool YGNode::isLeadingPositionDefined(const YGFlexDirection& axis) const { + return (YGFlexDirectionIsRow(axis) && + YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined) + ->unit != YGUnitUndefined) || + YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined) + ->unit != YGUnitUndefined; + } + + bool YGNode::isTrailingPosDefined(const YGFlexDirection& axis) const { + return (YGFlexDirectionIsRow(axis) && + YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined) + ->unit != YGUnitUndefined) || + YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined) + ->unit != YGUnitUndefined; + } + + YGFloatOptional YGNode::getLeadingMargin( + const YGFlexDirection& axis, + const float& widthSize) const { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeStart].unit != YGUnitUndefined) { + return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize); + } + + return YGResolveValueMargin( + *YGComputedEdgeValue(style_.margin, leading[axis], &YGValueZero), + widthSize); + } + + YGFloatOptional YGNode::getTrailingMargin( + const YGFlexDirection& axis, + const float& widthSize) const { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { + return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize); + } + + return YGResolveValueMargin( + *YGComputedEdgeValue(style_.margin, trailing[axis], &YGValueZero), + widthSize); + } + + YGFloatOptional YGNode::getMarginForAxis( + const YGFlexDirection& axis, + const float& widthSize) const { + return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); + } + + // Setters + + void YGNode::setContext(void* context) { + context_ = context; + } + + void YGNode::setPrintFunc(YGPrintFunc printFunc) { + print_ = printFunc; + } + + void YGNode::setHasNewLayout(bool hasNewLayout) { + hasNewLayout_ = hasNewLayout; + } + + void YGNode::setNodeType(YGNodeType nodeType) { + nodeType_ = nodeType; + } + + void YGNode::setStyleFlexDirection(YGFlexDirection direction) { + style_.flexDirection = direction; + } + + void YGNode::setStyleAlignContent(YGAlign alignContent) { + style_.alignContent = alignContent; + } + + void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { + if (measureFunc == nullptr) { + measure_ = nullptr; + // TODO: t18095186 Move nodeType to opt-in function and mark appropriate + // places in Litho + nodeType_ = YGNodeTypeDefault; + } else { + YGAssertWithNode( + this, + children_.size() == 0, + "Cannot set measure function: Nodes with measure functions cannot have children."); + measure_ = measureFunc; + // TODO: t18095186 Move nodeType to opt-in function and mark appropriate + // places in Litho + setNodeType(YGNodeTypeText); + } + + measure_ = measureFunc; + } + + void YGNode::setBaseLineFunc(YGBaselineFunc baseLineFunc) { + baseline_ = baseLineFunc; + } + + void YGNode::setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { + dirtied_ = dirtiedFunc; + } + + void YGNode::setStyle(const YGStyle& style) { + style_ = style; + } + + void YGNode::setLayout(const YGLayout& layout) { + layout_ = layout; + } + + void YGNode::setLineIndex(uint32_t lineIndex) { + lineIndex_ = lineIndex; + } + + void YGNode::setOwner(YGNodeRef owner) { + owner_ = owner; + } + + void YGNode::setChildren(const YGVector& children) { + children_ = children; + } + + void YGNode::setNextChild(YGNodeRef nextChild) { + nextChild_ = nextChild; + } + + void YGNode::replaceChild(YGNodeRef child, uint32_t index) { + children_[index] = child; + } + + void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) { + std::replace(children_.begin(), children_.end(), oldChild, newChild); + } + + void YGNode::insertChild(YGNodeRef child, uint32_t index) { + children_.insert(children_.begin() + index, child); + } + + void YGNode::setConfig(YGConfigRef config) { + config_ = config; + } + + void YGNode::setDirty(bool isDirty) { + if (isDirty == isDirty_) { + return; + } + isDirty_ = isDirty; + if (isDirty && dirtied_) { + dirtied_(this); + } + } + + bool YGNode::removeChild(YGNodeRef child) { + std::vector::iterator p = + std::find(children_.begin(), children_.end(), child); + if (p != children_.end()) { + children_.erase(p); + return true; + } + return false; + } + + void YGNode::removeChild(uint32_t index) { + children_.erase(children_.begin() + index); + } + + void YGNode::setLayoutDirection(YGDirection direction) { + layout_.direction = direction; + } + + void YGNode::setLayoutMargin(float margin, int index) { + layout_.margin[index] = margin; + } + + void YGNode::setLayoutBorder(float border, int index) { + layout_.border[index] = border; + } + + void YGNode::setLayoutPadding(float padding, int index) { + layout_.padding[index] = padding; + } + + void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { + layout_.lastOwnerDirection = direction; + } + + void YGNode::setLayoutComputedFlexBasis( + const YGFloatOptional& computedFlexBasis) { + layout_.computedFlexBasis = computedFlexBasis; + } + + void YGNode::setLayoutPosition(float position, int index) { + layout_.position[index] = position; + } + + void YGNode::setLayoutComputedFlexBasisGeneration( + uint32_t computedFlexBasisGeneration) { + layout_.computedFlexBasisGeneration = computedFlexBasisGeneration; + } + + void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) { + layout_.measuredDimensions[index] = measuredDimension; + } + + void YGNode::setLayoutHadOverflow(bool hadOverflow) { + layout_.hadOverflow = hadOverflow; + } + + void YGNode::setLayoutDimension(float dimension, int index) { + layout_.dimensions[index] = dimension; + } + + // If both left and right are defined, then use left. Otherwise return + // +left or -right depending on which is defined. + YGFloatOptional YGNode::relativePosition( + const YGFlexDirection& axis, + const float& axisSize) const { + if (isLeadingPositionDefined(axis)) { + return getLeadingPosition(axis, axisSize); + } + + YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); + if (!trailingPosition.isUndefined()) { + trailingPosition.setValue(-1 * trailingPosition.getValue()); + } + return trailingPosition; + } + + void YGNode::setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float ownerWidth) { + /* Root nodes should be always layouted as LTR, so we don't return negative + * values. */ + const YGDirection directionRespectingRoot = + owner_ != nullptr ? direction : YGDirectionLTR; + const YGFlexDirection mainAxis = + YGResolveFlexDirection(style_.flexDirection, directionRespectingRoot); + const YGFlexDirection crossAxis = + YGFlexDirectionCross(mainAxis, directionRespectingRoot); + + const YGFloatOptional relativePositionMain = + relativePosition(mainAxis, mainSize); + const YGFloatOptional relativePositionCross = + relativePosition(crossAxis, crossSize); + + setLayoutPosition( + YGUnwrapFloatOptional( + getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), + leading[mainAxis]); + setLayoutPosition( + YGUnwrapFloatOptional( + getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), + trailing[mainAxis]); + setLayoutPosition( + YGUnwrapFloatOptional( + getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), + leading[crossAxis]); + setLayoutPosition( + YGUnwrapFloatOptional( + getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), + trailing[crossAxis]); + } + + YGNode::YGNode() + : context_(nullptr), + print_(nullptr), + hasNewLayout_(true), + nodeType_(YGNodeTypeDefault), + measure_(nullptr), + baseline_(nullptr), + dirtied_(nullptr), + style_(YGStyle()), + layout_(YGLayout()), + lineIndex_(0), + owner_(nullptr), + children_(YGVector()), + nextChild_(nullptr), + config_(nullptr), + isDirty_(false), + resolvedDimensions_({{YGValueUndefined, YGValueUndefined}}) {} + + YGNode::YGNode(const YGNode& node) + : context_(node.context_), + print_(node.print_), + hasNewLayout_(node.hasNewLayout_), + nodeType_(node.nodeType_), + measure_(node.measure_), + baseline_(node.baseline_), + dirtied_(node.dirtied_), + style_(node.style_), + layout_(node.layout_), + lineIndex_(node.lineIndex_), + owner_(node.owner_), + children_(node.children_), + nextChild_(node.nextChild_), + config_(node.config_), + isDirty_(node.isDirty_), + resolvedDimensions_(node.resolvedDimensions_) {} + + YGNode::YGNode(const YGConfigRef newConfig) : YGNode() { + config_ = newConfig; + } + + YGNode::YGNode( + void* context, + YGPrintFunc print, + bool hasNewLayout, + YGNodeType nodeType, + YGMeasureFunc measure, + YGBaselineFunc baseline, + YGDirtiedFunc dirtied, + const YGStyle& style, + const YGLayout& layout, + uint32_t lineIndex, + YGNodeRef owner, + const YGVector& children, + YGNodeRef nextChild, + YGConfigRef config, + bool isDirty, + std::array resolvedDimensions) + : context_(context), + print_(print), + hasNewLayout_(hasNewLayout), + nodeType_(nodeType), + measure_(measure), + baseline_(baseline), + dirtied_(dirtied), + style_(style), + layout_(layout), + lineIndex_(lineIndex), + owner_(owner), + children_(children), + nextChild_(nextChild), + config_(config), + isDirty_(isDirty), + resolvedDimensions_(resolvedDimensions) {} + + YGNode& YGNode::operator=(const YGNode& node) { + if (&node == this) { + return *this; + } + + for (auto child : children_) { + delete child; + } + + context_ = node.getContext(); + print_ = node.getPrintFunc(); + hasNewLayout_ = node.getHasNewLayout(); + nodeType_ = node.getNodeType(); + measure_ = node.getMeasure(); + baseline_ = node.getBaseline(); + dirtied_ = node.getDirtied(); + style_ = node.style_; + layout_ = node.layout_; + lineIndex_ = node.getLineIndex(); + owner_ = node.getOwner(); + children_ = node.getChildren(); + nextChild_ = node.getNextChild(); + config_ = node.getConfig(); + isDirty_ = node.isDirty(); + resolvedDimensions_ = node.getResolvedDimensions(); + + return *this; + } + + YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeStart].unit != YGUnitUndefined) { + return style_.margin[YGEdgeStart]; + } else { + return style_.margin[leading[axis]]; + } + } + + YGValue YGNode::marginTrailingValue(const YGFlexDirection axis) const { + if (YGFlexDirectionIsRow(axis) && + style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { + return style_.margin[YGEdgeEnd]; + } else { + return style_.margin[trailing[axis]]; + } + } + + YGValue YGNode::resolveFlexBasisPtr() const { + YGValue flexBasis = style_.flexBasis; + if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { + return flexBasis; + } + if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { + return config_->useWebDefaults ? YGValueAuto : YGValueZero; + } + return YGValueAuto; + } + + void YGNode::resolveDimension() { + for (uint32_t dim = YGDimensionWidth; dim < YGDimensionCount; dim++) { + if (getStyle().maxDimensions[dim].unit != YGUnitUndefined && + YGValueEqual( + getStyle().maxDimensions[dim], style_.minDimensions[dim])) { + resolvedDimensions_[dim] = style_.maxDimensions[dim]; + } else { + resolvedDimensions_[dim] = style_.dimensions[dim]; + } + } + } + + YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) { + if (style_.direction == YGDirectionInherit) { + return ownerDirection > YGDirectionInherit ? ownerDirection + : YGDirectionLTR; + } else { + return style_.direction; + } + } + + void YGNode::clearChildren() { + children_.clear(); + children_.shrink_to_fit(); + } + + YGNode::~YGNode() { + // All the member variables are deallocated externally, so no need to + // deallocate here + } + + // Other Methods + + void YGNode::cloneChildrenIfNeeded() { + // YGNodeRemoveChild in yoga.cpp has a forked variant of this algorithm + // optimized for deletions. + + const uint32_t childCount = static_cast(children_.size()); + if (childCount == 0) { + // This is an empty set. Nothing to clone. + return; + } + + const YGNodeRef firstChild = children_.front(); + if (firstChild->getOwner() == this) { + // If the first child has this node as its owner, we assume that it is + // already unique. We can do this because if we have it has a child, that + // means that its owner was at some point cloned which made that subtree + // immutable. We also assume that all its sibling are cloned as well. + return; + } + + const YGCloneNodeFunc cloneNodeCallback = config_->cloneNodeCallback; + for (uint32_t i = 0; i < childCount; ++i) { + const YGNodeRef oldChild = children_[i]; + YGNodeRef newChild = nullptr; + if (cloneNodeCallback) { + newChild = cloneNodeCallback(oldChild, this, i); + } + if (newChild == nullptr) { + newChild = YGNodeClone(oldChild); + } + replaceChild(newChild, i); + newChild->setOwner(this); + } + } + + void YGNode::markDirtyAndPropogate() { + if (!isDirty_) { + setDirty(true); + setLayoutComputedFlexBasis(YGFloatOptional()); + if (owner_) { + owner_->markDirtyAndPropogate(); + } + } + } + + void YGNode::markDirtyAndPropogateDownwards() { + isDirty_ = true; + for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) { + childNode->markDirtyAndPropogateDownwards(); + }); + } + + float YGNode::resolveFlexGrow() { + // Root nodes flexGrow should always be 0 + if (owner_ == nullptr) { + return 0.0; + } + if (!style_.flexGrow.isUndefined()) { + return style_.flexGrow.getValue(); + } + if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { + return style_.flex.getValue(); + } + return kDefaultFlexGrow; + } + + float YGNode::resolveFlexShrink() { + if (owner_ == nullptr) { + return 0.0; + } + if (!style_.flexShrink.isUndefined()) { + return style_.flexShrink.getValue(); + } + if (!config_->useWebDefaults && !style_.flex.isUndefined() && + style_.flex.getValue() < 0.0f) { + return -style_.flex.getValue(); + } + return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink; + } + + bool YGNode::isNodeFlexible() { + return ( + (style_.positionType == YGPositionTypeRelative) && + (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); + } + + float YGNode::getLeadingBorder(const YGFlexDirection& axis) const { + if (YGFlexDirectionIsRow(axis) && + style_.border[YGEdgeStart].unit != YGUnitUndefined && + !YGFloatIsUndefined(style_.border[YGEdgeStart].value) && + style_.border[YGEdgeStart].value >= 0.0f) { + return style_.border[YGEdgeStart].value; + } + + float computedEdgeValue = + YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value; + return YGFloatMax(computedEdgeValue, 0.0f); + } + + float YGNode::getTrailingBorder(const YGFlexDirection& flexDirection) const { + if (YGFlexDirectionIsRow(flexDirection) && + style_.border[YGEdgeEnd].unit != YGUnitUndefined && + !YGFloatIsUndefined(style_.border[YGEdgeEnd].value) && + style_.border[YGEdgeEnd].value >= 0.0f) { + return style_.border[YGEdgeEnd].value; + } + + float computedEdgeValue = + YGComputedEdgeValue(style_.border, trailing[flexDirection], &YGValueZero) + ->value; + return YGFloatMax(computedEdgeValue, 0.0f); + } + + YGFloatOptional YGNode::getLeadingPadding( + const YGFlexDirection& axis, + const float& widthSize) const { + const YGFloatOptional& paddingEdgeStart = + YGResolveValue(style_.padding[YGEdgeStart], widthSize); + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeStart].unit != YGUnitUndefined && + !paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() > 0.0f) { + return paddingEdgeStart; + } + + YGFloatOptional resolvedValue = YGResolveValue( + *YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero), + widthSize); + return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); + } + + YGFloatOptional YGNode::getTrailingPadding( + const YGFlexDirection& axis, + const float& widthSize) const { + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeEnd].unit != YGUnitUndefined && + !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && + YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) { + return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + } + + YGFloatOptional resolvedValue = YGResolveValue( + *YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero), + widthSize); + + return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); + } + + YGFloatOptional YGNode::getLeadingPaddingAndBorder( + const YGFlexDirection& axis, + const float& widthSize) const { + return getLeadingPadding(axis, widthSize) + + YGFloatOptional(getLeadingBorder(axis)); + } + + YGFloatOptional YGNode::getTrailingPaddingAndBorder( + const YGFlexDirection& axis, + const float& widthSize) const { + return getTrailingPadding(axis, widthSize) + + YGFloatOptional(getTrailingBorder(axis)); + } + + bool YGNode::didUseLegacyFlag() { + bool didUseLegacyFlag = layout_.didUseLegacyFlag; + if (didUseLegacyFlag) { + return true; + } + for (const auto& child : children_) { + if (child->layout_.didUseLegacyFlag) { + didUseLegacyFlag = true; + break; + } + } + return didUseLegacyFlag; + } + + void YGNode::setAndPropogateUseLegacyFlag(bool useLegacyFlag) { + config_->useLegacyStretchBehaviour = useLegacyFlag; + for_each(children_.begin(), children_.end(), [=](YGNodeRef childNode) { + childNode->getConfig()->useLegacyStretchBehaviour = useLegacyFlag; + }); + } + + void YGNode::setLayoutDoesLegacyFlagAffectsLayout( + bool doesLegacyFlagAffectsLayout) { + layout_.doesLegacyStretchFlagAffectsLayout = doesLegacyFlagAffectsLayout; + } + + void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) { + layout_.didUseLegacyFlag = didUseLegacyFlag; + } + + bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const { + if (children_.size() != node.children_.size()) { + return false; + } + if (layout_ != node.layout_) { + return false; + } + if (children_.size() == 0) { + return true; + } + + bool isLayoutTreeEqual = true; + YGNodeRef otherNodeChildren = nullptr; + for (std::vector::size_type i = 0; i < children_.size(); ++i) { + otherNodeChildren = node.children_[i]; + isLayoutTreeEqual = + children_[i]->isLayoutTreeEqualToNode(*otherNodeChildren); + if (!isLayoutTreeEqual) { + return false; + } + } + return isLayoutTreeEqual; + } diff --cc dali-toolkit/third-party/yoga/YGNode.h index 0000000,186798b..ee59cf3 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGNode.h +++ b/dali-toolkit/third-party/yoga/YGNode.h @@@ -1,0 -1,184 +1,184 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include + #include "YGConfig.h" + #include "YGLayout.h" + #include "YGStyle.h" + #include "Yoga-internal.h" + + struct YGNode { + private: + void* context_; + YGPrintFunc print_; + bool hasNewLayout_; + YGNodeType nodeType_; + YGMeasureFunc measure_; + YGBaselineFunc baseline_; + YGDirtiedFunc dirtied_; + YGStyle style_; + YGLayout layout_; + uint32_t lineIndex_; + YGNodeRef owner_; + YGVector children_; + YGNodeRef nextChild_; + YGConfigRef config_; + bool isDirty_; + std::array resolvedDimensions_; + + YGFloatOptional relativePosition( + const YGFlexDirection& axis, + const float& axisSize) const; + + public: + YGNode(); + ~YGNode(); + explicit YGNode(const YGConfigRef newConfig); + YGNode(const YGNode& node); + YGNode& operator=(const YGNode& node); + YGNode( + void* context, + YGPrintFunc print, + bool hasNewLayout, + YGNodeType nodeType, + YGMeasureFunc measure, + YGBaselineFunc baseline, + YGDirtiedFunc dirtied, + const YGStyle& style, + const YGLayout& layout, + uint32_t lineIndex, + YGNodeRef owner, + const YGVector& children, + YGNodeRef nextChild, + YGConfigRef config, + bool isDirty, + std::array resolvedDimensions); + + // Getters + void* getContext() const; + YGPrintFunc getPrintFunc() const; + bool getHasNewLayout() const; + YGNodeType getNodeType() const; + YGMeasureFunc getMeasure() const; + YGBaselineFunc getBaseline() const; + YGDirtiedFunc getDirtied() const; + // For Performance reasons passing as reference. + YGStyle& getStyle(); + // For Performance reasons passing as reference. + YGLayout& getLayout(); + uint32_t getLineIndex() const; + // returns the YGNodeRef that owns this YGNode. An owner is used to identify + // the YogaTree that a YGNode belongs to. + // This method will return the parent of the YGNode when a YGNode only belongs + // to one YogaTree or nullptr when the YGNode is shared between two or more + // YogaTrees. + YGNodeRef getOwner() const; + YGVector getChildren() const; + uint32_t getChildrenCount() const; + YGNodeRef getChild(uint32_t index) const; + YGNodeRef getNextChild() const; + YGConfigRef getConfig() const; + bool isDirty() const; + std::array getResolvedDimensions() const; + YGValue getResolvedDimension(int index); + + // Methods related to positions, margin, padding and border + YGFloatOptional getLeadingPosition(const YGFlexDirection& axis, + const float& axisSize) const; + bool isLeadingPositionDefined(const YGFlexDirection& axis) const; + bool isTrailingPosDefined(const YGFlexDirection& axis) const; + YGFloatOptional getTrailingPosition( + const YGFlexDirection& axis, + const float& axisSize) const; + YGFloatOptional getLeadingMargin( + const YGFlexDirection& axis, + const float& widthSize) const; + YGFloatOptional getTrailingMargin( + const YGFlexDirection& axis, + const float& widthSize) const; + float getLeadingBorder(const YGFlexDirection& flexDirection) const; + float getTrailingBorder(const YGFlexDirection& flexDirection) const; + YGFloatOptional getLeadingPadding( + const YGFlexDirection& axis, + const float& widthSize) const; + YGFloatOptional getTrailingPadding( + const YGFlexDirection& axis, + const float& widthSize) const; + YGFloatOptional getLeadingPaddingAndBorder( + const YGFlexDirection& axis, + const float& widthSize) const; + YGFloatOptional getTrailingPaddingAndBorder( + const YGFlexDirection& axis, + const float& widthSize) const; + YGFloatOptional getMarginForAxis( + const YGFlexDirection& axis, + const float& widthSize) const; + // Setters + + void setContext(void* context); + void setPrintFunc(YGPrintFunc printFunc); + void setHasNewLayout(bool hasNewLayout); + void setNodeType(YGNodeType nodeTye); + void setMeasureFunc(YGMeasureFunc measureFunc); + void setBaseLineFunc(YGBaselineFunc baseLineFunc); + void setDirtiedFunc(YGDirtiedFunc dirtiedFunc); + void setStyle(const YGStyle& style); + void setStyleFlexDirection(YGFlexDirection direction); + void setStyleAlignContent(YGAlign alignContent); + void setLayout(const YGLayout& layout); + void setLineIndex(uint32_t lineIndex); + void setOwner(YGNodeRef owner); + void setChildren(const YGVector& children); + void setNextChild(YGNodeRef nextChild); + void setConfig(YGConfigRef config); + void setDirty(bool isDirty); + void setLayoutLastOwnerDirection(YGDirection direction); + void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); + void setLayoutComputedFlexBasisGeneration( + uint32_t computedFlexBasisGeneration); + void setLayoutMeasuredDimension(float measuredDimension, int index); + void setLayoutHadOverflow(bool hadOverflow); + void setLayoutDimension(float dimension, int index); + void setLayoutDirection(YGDirection direction); + void setLayoutMargin(float margin, int index); + void setLayoutBorder(float border, int index); + void setLayoutPadding(float padding, int index); + void setLayoutPosition(float position, int index); + void setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float ownerWidth); + void setAndPropogateUseLegacyFlag(bool useLegacyFlag); + void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout); + void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag); + void markDirtyAndPropogateDownwards(); + + // Other methods + YGValue marginLeadingValue(const YGFlexDirection axis) const; + YGValue marginTrailingValue(const YGFlexDirection axis) const; + YGValue resolveFlexBasisPtr() const; + void resolveDimension(); + YGDirection resolveDirection(const YGDirection ownerDirection); + void clearChildren(); + /// Replaces the occurrences of oldChild with newChild + void replaceChild(YGNodeRef oldChild, YGNodeRef newChild); + void replaceChild(YGNodeRef child, uint32_t index); + void insertChild(YGNodeRef child, uint32_t index); + /// Removes the first occurrence of child + bool removeChild(YGNodeRef child); + void removeChild(uint32_t index); + + void cloneChildrenIfNeeded(); + void markDirtyAndPropogate(); + float resolveFlexGrow(); + float resolveFlexShrink(); + bool isNodeFlexible(); + bool didUseLegacyFlag(); + bool isLayoutTreeEqualToNode(const YGNode& node) const; + }; diff --cc dali-toolkit/third-party/yoga/YGNodePrint.cpp index 0000000,ab3aa7c..7644629 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGNodePrint.cpp +++ b/dali-toolkit/third-party/yoga/YGNodePrint.cpp @@@ -1,0 -1,231 +1,231 @@@ + /* - * Copyright (c) 2017-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGNodePrint.h" + #include + #include "YGEnums.h" + #include "YGNode.h" + #include "Yoga-internal.h" + + namespace facebook { + namespace yoga { + typedef std::string string; + + static void indent(string* base, uint32_t level) { + for (uint32_t i = 0; i < level; ++i) { + base->append(" "); + } + } + + static bool areFourValuesEqual(const std::array& four) { + return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && + YGValueEqual(four[0], four[3]); + } + + static void appendFormatedString(string* str, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + va_list argsCopy; + va_copy(argsCopy, args); + std::vector buf(1 + vsnprintf(NULL, 0, fmt, args)); + va_end(args); + vsnprintf(buf.data(), buf.size(), fmt, argsCopy); + va_end(argsCopy); + string result = string(buf.begin(), buf.end() - 1); + str->append(result); + } + + static void appendFloatOptionalIfDefined( + string* base, + const string key, + const YGFloatOptional num) { + if (!num.isUndefined()) { + appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue()); + } + } + + static void appendNumberIfNotUndefined( + string* base, + const string key, + const YGValue number) { + if (number.unit != YGUnitUndefined) { + if (number.unit == YGUnitAuto) { + base->append(key + ": auto; "); + } else { + string unit = number.unit == YGUnitPoint ? "px" : "%%"; + appendFormatedString( + base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str()); + } + } + } + + static void + appendNumberIfNotAuto(string* base, const string& key, const YGValue number) { + if (number.unit != YGUnitAuto) { + appendNumberIfNotUndefined(base, key, number); + } + } + + static void + appendNumberIfNotZero(string* base, const string& str, const YGValue number) { + + if (number.unit == YGUnitAuto) { + base->append(str + ": auto; "); + } else if (!YGFloatsEqual(number.value, 0)) { + appendNumberIfNotUndefined(base, str, number); + } + } + + static void appendEdges( + string* base, + const string& key, + const std::array& edges) { + if (areFourValuesEqual(edges)) { + appendNumberIfNotZero(base, key, edges[YGEdgeLeft]); + } else { + for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) { + string str = key + "-" + YGEdgeToString(static_cast(edge)); + appendNumberIfNotZero(base, str, edges[edge]); + } + } + } + + static void appendEdgeIfNotUndefined( + string* base, + const string& str, + const std::array& edges, + const YGEdge edge) { + appendNumberIfNotUndefined( + base, str, *YGComputedEdgeValue(edges, edge, &YGValueUndefined)); + } + + void YGNodeToString( + std::string* str, + YGNodeRef node, + YGPrintOptions options, + uint32_t level) { + indent(str, level); + appendFormatedString(str, "
getPrintFunc() != nullptr) { + node->getPrintFunc()(node); + } + + if (options & YGPrintOptionsLayout) { + appendFormatedString(str, "layout=\""); + appendFormatedString( + str, "width: %g; ", node->getLayout().dimensions[YGDimensionWidth]); + appendFormatedString( + str, "height: %g; ", node->getLayout().dimensions[YGDimensionHeight]); + appendFormatedString( + str, "top: %g; ", node->getLayout().position[YGEdgeTop]); + appendFormatedString( + str, "left: %g;", node->getLayout().position[YGEdgeLeft]); + appendFormatedString(str, "\" "); + } + + if (options & YGPrintOptionsStyle) { + appendFormatedString(str, "style=\""); + if (node->getStyle().flexDirection != YGNode().getStyle().flexDirection) { + appendFormatedString( + str, + "flex-direction: %s; ", + YGFlexDirectionToString(node->getStyle().flexDirection)); + } + if (node->getStyle().justifyContent != YGNode().getStyle().justifyContent) { + appendFormatedString( + str, + "justify-content: %s; ", + YGJustifyToString(node->getStyle().justifyContent)); + } + if (node->getStyle().alignItems != YGNode().getStyle().alignItems) { + appendFormatedString( + str, + "align-items: %s; ", + YGAlignToString(node->getStyle().alignItems)); + } + if (node->getStyle().alignContent != YGNode().getStyle().alignContent) { + appendFormatedString( + str, + "align-content: %s; ", + YGAlignToString(node->getStyle().alignContent)); + } + if (node->getStyle().alignSelf != YGNode().getStyle().alignSelf) { + appendFormatedString( + str, "align-self: %s; ", YGAlignToString(node->getStyle().alignSelf)); + } + appendFloatOptionalIfDefined(str, "flex-grow", node->getStyle().flexGrow); + appendFloatOptionalIfDefined( + str, "flex-shrink", node->getStyle().flexShrink); + appendNumberIfNotAuto(str, "flex-basis", node->getStyle().flexBasis); + appendFloatOptionalIfDefined(str, "flex", node->getStyle().flex); + + if (node->getStyle().flexWrap != YGNode().getStyle().flexWrap) { + appendFormatedString( + str, "flexWrap: %s; ", YGWrapToString(node->getStyle().flexWrap)); + } + + if (node->getStyle().overflow != YGNode().getStyle().overflow) { + appendFormatedString( + str, "overflow: %s; ", YGOverflowToString(node->getStyle().overflow)); + } + + if (node->getStyle().display != YGNode().getStyle().display) { + appendFormatedString( + str, "display: %s; ", YGDisplayToString(node->getStyle().display)); + } + appendEdges(str, "margin", node->getStyle().margin); + appendEdges(str, "padding", node->getStyle().padding); + appendEdges(str, "border", node->getStyle().border); + + appendNumberIfNotAuto( + str, "width", node->getStyle().dimensions[YGDimensionWidth]); + appendNumberIfNotAuto( + str, "height", node->getStyle().dimensions[YGDimensionHeight]); + appendNumberIfNotAuto( + str, "max-width", node->getStyle().maxDimensions[YGDimensionWidth]); + appendNumberIfNotAuto( + str, "max-height", node->getStyle().maxDimensions[YGDimensionHeight]); + appendNumberIfNotAuto( + str, "min-width", node->getStyle().minDimensions[YGDimensionWidth]); + appendNumberIfNotAuto( + str, "min-height", node->getStyle().minDimensions[YGDimensionHeight]); + + if (node->getStyle().positionType != YGNode().getStyle().positionType) { + appendFormatedString( + str, + "position: %s; ", + YGPositionTypeToString(node->getStyle().positionType)); + } + + appendEdgeIfNotUndefined( + str, "left", node->getStyle().position, YGEdgeLeft); + appendEdgeIfNotUndefined( + str, "right", node->getStyle().position, YGEdgeRight); + appendEdgeIfNotUndefined(str, "top", node->getStyle().position, YGEdgeTop); + appendEdgeIfNotUndefined( + str, "bottom", node->getStyle().position, YGEdgeBottom); + appendFormatedString(str, "\" "); + + if (node->getMeasure() != nullptr) { + appendFormatedString(str, "has-custom-measure=\"true\""); + } + } + appendFormatedString(str, ">"); + + const uint32_t childCount = static_cast(node->getChildren().size()); + if (options & YGPrintOptionsChildren && childCount > 0) { + for (uint32_t i = 0; i < childCount; i++) { + appendFormatedString(str, "\n"); + YGNodeToString(str, YGNodeGetChild(node, i), options, level + 1); + } + appendFormatedString(str, "\n"); + indent(str, level); + } + appendFormatedString(str, "
"); + } + } // namespace yoga + } // namespace facebook diff --cc dali-toolkit/third-party/yoga/YGNodePrint.h index 0000000,16259fc..d2e1677 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGNodePrint.h +++ b/dali-toolkit/third-party/yoga/YGNodePrint.h @@@ -1,0 -1,22 +1,22 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + #pragma once + #include + + #include "Yoga.h" + + namespace facebook { + namespace yoga { + + void YGNodeToString( + std::string* str, + YGNodeRef node, + YGPrintOptions options, + uint32_t level); + + } // namespace yoga + } // namespace facebook diff --cc dali-toolkit/third-party/yoga/YGStyle.cpp index 0000000,c11dc4e..48031d6 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGStyle.cpp +++ b/dali-toolkit/third-party/yoga/YGStyle.cpp @@@ -1,0 -1,106 +1,106 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "YGStyle.h" + + const YGValue kYGValueUndefined = {0, YGUnitUndefined}; + + const YGValue kYGValueAuto = {0, YGUnitAuto}; + + const std::array kYGDefaultEdgeValuesUnit = { + {kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined}}; + + const std::array kYGDefaultDimensionValuesAutoUnit = { + {kYGValueAuto, kYGValueAuto}}; + + const std::array kYGDefaultDimensionValuesUnit = { + {kYGValueUndefined, kYGValueUndefined}}; + + YGStyle::YGStyle() + : direction(YGDirectionInherit), + flexDirection(YGFlexDirectionColumn), + justifyContent(YGJustifyFlexStart), + alignContent(YGAlignFlexStart), + alignItems(YGAlignStretch), + alignSelf(YGAlignAuto), + positionType(YGPositionTypeRelative), + flexWrap(YGWrapNoWrap), + overflow(YGOverflowVisible), + display(YGDisplayFlex), + flex(YGFloatOptional()), + flexGrow(YGFloatOptional()), + flexShrink(YGFloatOptional()), + flexBasis(kYGValueAuto), + margin(kYGDefaultEdgeValuesUnit), + position(kYGDefaultEdgeValuesUnit), + padding(kYGDefaultEdgeValuesUnit), + border(kYGDefaultEdgeValuesUnit), + dimensions(kYGDefaultDimensionValuesAutoUnit), + minDimensions(kYGDefaultDimensionValuesUnit), + maxDimensions(kYGDefaultDimensionValuesUnit), + aspectRatio(YGFloatOptional()) {} + + // Yoga specific properties, not compatible with flexbox specification + bool YGStyle::operator==(const YGStyle& style) { + bool areNonFloatValuesEqual = direction == style.direction && + flexDirection == style.flexDirection && + justifyContent == style.justifyContent && + alignContent == style.alignContent && alignItems == style.alignItems && + alignSelf == style.alignSelf && positionType == style.positionType && + flexWrap == style.flexWrap && overflow == style.overflow && + display == style.display && YGValueEqual(flexBasis, style.flexBasis) && + YGValueArrayEqual(margin, style.margin) && + YGValueArrayEqual(position, style.position) && + YGValueArrayEqual(padding, style.padding) && + YGValueArrayEqual(border, style.border) && + YGValueArrayEqual(dimensions, style.dimensions) && + YGValueArrayEqual(minDimensions, style.minDimensions) && + YGValueArrayEqual(maxDimensions, style.maxDimensions); + + areNonFloatValuesEqual = + areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined(); + if (areNonFloatValuesEqual && !flex.isUndefined() && + !style.flex.isUndefined()) { + areNonFloatValuesEqual = + areNonFloatValuesEqual && flex.getValue() == style.flex.getValue(); + } + + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexGrow.isUndefined() == style.flexGrow.isUndefined(); + if (areNonFloatValuesEqual && !flexGrow.isUndefined()) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexGrow.getValue() == style.flexGrow.getValue(); + } + + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexShrink.isUndefined() == style.flexShrink.isUndefined(); + if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexShrink.getValue() == style.flexShrink.getValue(); + } + + if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + aspectRatio.getValue() == style.aspectRatio.getValue(); + } + + return areNonFloatValuesEqual; + } + + bool YGStyle::operator!=(const YGStyle& style) { + return !(*this == style); + } + + YGStyle::~YGStyle() {} diff --cc dali-toolkit/third-party/yoga/YGStyle.h index 0000000,0aaba54..6c13f92 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/YGStyle.h +++ b/dali-toolkit/third-party/yoga/YGStyle.h @@@ -1,0 -1,43 +1,43 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include "YGFloatOptional.h" + #include "Yoga-internal.h" + #include "Yoga.h" + + struct YGStyle { + YGDirection direction; + YGFlexDirection flexDirection; + YGJustify justifyContent; + YGAlign alignContent; + YGAlign alignItems; + YGAlign alignSelf; + YGPositionType positionType; + YGWrap flexWrap; + YGOverflow overflow; + YGDisplay display; + YGFloatOptional flex; + YGFloatOptional flexGrow; + YGFloatOptional flexShrink; + YGValue flexBasis; + std::array margin; + std::array position; + std::array padding; + std::array border; + std::array dimensions; + std::array minDimensions; + std::array maxDimensions; + YGFloatOptional aspectRatio; + + YGStyle(); + // Yoga specific properties, not compatible with flexbox specification + bool operator==(const YGStyle& style); + + bool operator!=(const YGStyle& style); + ~YGStyle(); + }; diff --cc dali-toolkit/third-party/yoga/Yoga-internal.h index 0000000,17dd9ef..1cea135 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/Yoga-internal.h +++ b/dali-toolkit/third-party/yoga/Yoga-internal.h @@@ -1,0 -1,100 +1,100 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + #include + #include + #include + #include + #include "Yoga.h" + + using YGVector = std::vector; + + YG_EXTERN_C_BEGIN + + WIN_EXPORT float YGRoundValueToPixelGrid(const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor); + + YG_EXTERN_C_END + + extern const std::array trailing; + extern const std::array leading; + extern bool YGValueEqual(const YGValue a, const YGValue b); + extern const YGValue YGValueUndefined; + extern const YGValue YGValueAuto; + extern const YGValue YGValueZero; + + template + bool YGValueArrayEqual( + const std::array val1, + const std::array val2) { + bool areEqual = true; + for (uint32_t i = 0; i < size && areEqual; ++i) { + areEqual = YGValueEqual(val1[i], val2[i]); + } + return areEqual; + } + + struct YGCachedMeasurement { + float availableWidth; + float availableHeight; + YGMeasureMode widthMeasureMode; + YGMeasureMode heightMeasureMode; + + float computedWidth; + float computedHeight; + + YGCachedMeasurement() + : availableWidth(0), + availableHeight(0), + widthMeasureMode((YGMeasureMode)-1), + heightMeasureMode((YGMeasureMode)-1), + computedWidth(-1), + computedHeight(-1) {} + + bool operator==(const YGCachedMeasurement& measurement) const { + bool isEqual = widthMeasureMode == measurement.widthMeasureMode && + heightMeasureMode == measurement.heightMeasureMode; + + if (!YGFloatIsUndefined(availableWidth) || + !YGFloatIsUndefined(measurement.availableWidth)) { + isEqual = isEqual && availableWidth == measurement.availableWidth; + } + if (!YGFloatIsUndefined(availableHeight) || + !YGFloatIsUndefined(measurement.availableHeight)) { + isEqual = isEqual && availableHeight == measurement.availableHeight; + } + if (!YGFloatIsUndefined(computedWidth) || + !YGFloatIsUndefined(measurement.computedWidth)) { + isEqual = isEqual && computedWidth == measurement.computedWidth; + } + if (!YGFloatIsUndefined(computedHeight) || + !YGFloatIsUndefined(measurement.computedHeight)) { + isEqual = isEqual && computedHeight == measurement.computedHeight; + } + + return isEqual; + } + }; + + // This value was chosen based on empiracle data. Even the most complicated + // layouts should not require more than 16 entries to fit within the cache. + #define YG_MAX_CACHED_RESULT_COUNT 16 + + + static const float kDefaultFlexGrow = 0.0f; + static const float kDefaultFlexShrink = 0.0f; + static const float kWebDefaultFlexShrink = 1.0f; + + extern bool YGFloatsEqual(const float a, const float b); + extern bool YGValueEqual(const YGValue a, const YGValue b); + extern const YGValue* YGComputedEdgeValue( + const std::array& edges, + const YGEdge edge, + const YGValue* const defaultValue); diff --cc dali-toolkit/third-party/yoga/Yoga.cpp index 0000000,a927ef5..7729153 mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/Yoga.cpp +++ b/dali-toolkit/third-party/yoga/Yoga.cpp @@@ -1,0 -1,4054 +1,4054 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #include "Yoga.h" + #include + #include + #include + #include "Utils.h" + #include "YGNode.h" + #include "YGNodePrint.h" + #include "Yoga-internal.h" + #ifdef _MSC_VER + #include + + /* define fmaxf if < VC12 */ + #if _MSC_VER < 1800 + __forceinline const float fmaxf(const float a, const float b) { + if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + return (a > b) ? a : b; + } + return YGFloatIsUndefined(a) ? b : a; + } + #endif + #endif + + #ifdef ANDROID + static int YGAndroidLog(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args); + #else + static int YGDefaultLog(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args); + #endif + + const YGValue YGValueZero = {0, YGUnitPoint}; + const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; + const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; + + #ifdef ANDROID + #include + static int YGAndroidLog(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args) { + int androidLevel = YGLogLevelDebug; + switch (level) { + case YGLogLevelFatal: + androidLevel = ANDROID_LOG_FATAL; + break; + case YGLogLevelError: + androidLevel = ANDROID_LOG_ERROR; + break; + case YGLogLevelWarn: + androidLevel = ANDROID_LOG_WARN; + break; + case YGLogLevelInfo: + androidLevel = ANDROID_LOG_INFO; + break; + case YGLogLevelDebug: + androidLevel = ANDROID_LOG_DEBUG; + break; + case YGLogLevelVerbose: + androidLevel = ANDROID_LOG_VERBOSE; + break; + } + const int result = __android_log_vprint(androidLevel, "yoga", format, args); + return result; + } + #else + #define YG_UNUSED(x) (void)(x); + + static int YGDefaultLog(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args) { + YG_UNUSED(config); + YG_UNUSED(node); + switch (level) { + case YGLogLevelError: + case YGLogLevelFatal: + return vfprintf(stderr, format, args); + case YGLogLevelWarn: + case YGLogLevelInfo: + case YGLogLevelDebug: + case YGLogLevelVerbose: + default: + return vprintf(format, args); + } + } + + #undef YG_UNUSED + #endif + + bool YGFloatIsUndefined(const float value) { + // Value of a float in the case of it being not defined is 10.1E20. Earlier + // it used to be NAN, the benefit of which was that if NAN is involved in any + // mathematical expression the result was NAN. But since we want to have + // `-ffast-math` flag being used by compiler which assumes that the floating + // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But + // now if YGUndefined is involved in any mathematical operations this + // value(10.1E20) would change. So the following check makes sure that if the + // value is outside a range (-10E8, 10E8) then it is undefined. + return value >= 10E8 || value <= -10E8; + } + + const YGValue* YGComputedEdgeValue( + const std::array& edges, + const YGEdge edge, + const YGValue* const defaultValue) { + if (edges[edge].unit != YGUnitUndefined) { + return &edges[edge]; + } + + if ((edge == YGEdgeTop || edge == YGEdgeBottom) && + edges[YGEdgeVertical].unit != YGUnitUndefined) { + return &edges[YGEdgeVertical]; + } + + if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart || edge == YGEdgeEnd) && + edges[YGEdgeHorizontal].unit != YGUnitUndefined) { + return &edges[YGEdgeHorizontal]; + } + + if (edges[YGEdgeAll].unit != YGUnitUndefined) { + return &edges[YGEdgeAll]; + } + + if (edge == YGEdgeStart || edge == YGEdgeEnd) { + return &YGValueUndefined; + } + + return defaultValue; + } + + void* YGNodeGetContext(YGNodeRef node) { + return node->getContext(); + } + + void YGNodeSetContext(YGNodeRef node, void* context) { + return node->setContext(context); + } + + YGMeasureFunc YGNodeGetMeasureFunc(YGNodeRef node) { + return node->getMeasure(); + } + + void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc) { + node->setMeasureFunc(measureFunc); + } + + YGBaselineFunc YGNodeGetBaselineFunc(YGNodeRef node) { + return node->getBaseline(); + } + + void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc) { + node->setBaseLineFunc(baselineFunc); + } + + YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) { + return node->getDirtied(); + } + + void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc) { + node->setDirtiedFunc(dirtiedFunc); + } + + YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node) { + return node->getPrintFunc(); + } + + void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) { + node->setPrintFunc(printFunc); + } + + bool YGNodeGetHasNewLayout(YGNodeRef node) { + return node->getHasNewLayout(); + } + + void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) { + node->setHasNewLayout(hasNewLayout); + } + + YGNodeType YGNodeGetNodeType(YGNodeRef node) { + return node->getNodeType(); + } + + void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) { + return node->setNodeType(nodeType); + } + + bool YGNodeIsDirty(YGNodeRef node) { + return node->isDirty(); + } + + bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node) { + return node->didUseLegacyFlag(); + } + + void YGNodeMarkDirtyAndPropogateToDescendants(const YGNodeRef node) { + return node->markDirtyAndPropogateDownwards(); + } + + int32_t gNodeInstanceCount = 0; + int32_t gConfigInstanceCount = 0; + + WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { + const YGNodeRef node = new YGNode(); + YGAssertWithConfig( + config, node != nullptr, "Could not allocate memory for node"); + gNodeInstanceCount++; + + if (config->useWebDefaults) { + node->setStyleFlexDirection(YGFlexDirectionRow); + node->setStyleAlignContent(YGAlignStretch); + } + node->setConfig(config); + return node; + } + + YGConfigRef YGConfigGetDefault() { + static YGConfigRef defaultConfig = YGConfigNew(); + return defaultConfig; + } + + YGNodeRef YGNodeNew(void) { + return YGNodeNewWithConfig(YGConfigGetDefault()); + } + + YGNodeRef YGNodeClone(YGNodeRef oldNode) { + YGNodeRef node = new YGNode(*oldNode); + YGAssertWithConfig( + oldNode->getConfig(), + node != nullptr, + "Could not allocate memory for node"); + gNodeInstanceCount++; + node->setOwner(nullptr); + return node; + } + + static YGConfigRef YGConfigClone(const YGConfig& oldConfig) { + const YGConfigRef config = new YGConfig(oldConfig); + YGAssert(config != nullptr, "Could not allocate memory for config"); + if (config == nullptr) { + abort(); + } + gConfigInstanceCount++; + return config; + } + + static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { + YGNodeRef node = YGNodeClone(oldNode); + YGVector vec = YGVector(); + vec.reserve(oldNode->getChildren().size()); + YGNodeRef childNode = nullptr; + for (auto& item : oldNode->getChildren()) { + childNode = YGNodeDeepClone(item); + childNode->setOwner(node); + vec.push_back(childNode); + } + node->setChildren(vec); + + if (oldNode->getConfig() != nullptr) { + node->setConfig(YGConfigClone(*(oldNode->getConfig()))); + } + + if (oldNode->getNextChild() != nullptr) { + node->setNextChild(YGNodeDeepClone(oldNode->getNextChild())); + } + + return node; + } + + void YGNodeFree(const YGNodeRef node) { + if (YGNodeRef owner = node->getOwner()) { + owner->removeChild(node); + node->setOwner(nullptr); + } + + const uint32_t childCount = YGNodeGetChildCount(node); + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + child->setOwner(nullptr); + } + + node->clearChildren(); + delete node; + gNodeInstanceCount--; + } + + static void YGConfigFreeRecursive(const YGNodeRef root) { + if (root->getConfig() != nullptr) { + gConfigInstanceCount--; + delete root->getConfig(); + } + // Delete configs recursively for childrens + for (uint32_t i = 0; i < root->getChildrenCount(); ++i) { + YGConfigFreeRecursive(root->getChild(i)); + } + } + + void YGNodeFreeRecursive(const YGNodeRef root) { + while (YGNodeGetChildCount(root) > 0) { + const YGNodeRef child = YGNodeGetChild(root, 0); + if (child->getOwner() != root) { + // Don't free shared nodes that we don't own. + break; + } + YGNodeRemoveChild(root, child); + YGNodeFreeRecursive(child); + } + YGNodeFree(root); + } + + void YGNodeReset(const YGNodeRef node) { + YGAssertWithNode(node, + YGNodeGetChildCount(node) == 0, + "Cannot reset a node which still has children attached"); + YGAssertWithNode( + node, + node->getOwner() == nullptr, + "Cannot reset a node still attached to a owner"); + + node->clearChildren(); + + const YGConfigRef config = node->getConfig(); + *node = YGNode(); + if (config->useWebDefaults) { + node->setStyleFlexDirection(YGFlexDirectionRow); + node->setStyleAlignContent(YGAlignStretch); + } + node->setConfig(config); + } + + int32_t YGNodeGetInstanceCount(void) { + return gNodeInstanceCount; + } + + int32_t YGConfigGetInstanceCount(void) { + return gConfigInstanceCount; + } + + YGConfigRef YGConfigNew(void) { + #ifdef ANDROID + const YGConfigRef config = new YGConfig(YGAndroidLog); + #else + const YGConfigRef config = new YGConfig(YGDefaultLog); + #endif + gConfigInstanceCount++; + return config; + } + + void YGConfigFree(const YGConfigRef config) { + free(config); + gConfigInstanceCount--; + } + + void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) { + memcpy(dest, src, sizeof(YGConfig)); + } + + void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) { + YGAssertWithNode( + node, + child->getOwner() == nullptr, + "Child already has a owner, it must be removed first."); + + YGAssertWithNode( + node, + node->getMeasure() == nullptr, + "Cannot add child: Nodes with measure functions cannot have children."); + + node->cloneChildrenIfNeeded(); + node->insertChild(child, index); + YGNodeRef owner = child->getOwner() ? nullptr : node; + child->setOwner(owner); + node->markDirtyAndPropogate(); + } + + void YGNodeInsertSharedChild( + const YGNodeRef node, + const YGNodeRef child, + const uint32_t index) { + YGAssertWithNode( + node, + node->getMeasure() == nullptr, + "Cannot add child: Nodes with measure functions cannot have children."); + + node->insertChild(child, index); + child->setOwner(nullptr); + node->markDirtyAndPropogate(); + } + + void YGNodeRemoveChild(const YGNodeRef owner, const YGNodeRef excludedChild) { + // This algorithm is a forked variant from cloneChildrenIfNeeded in YGNode + // that excludes a child. + const uint32_t childCount = YGNodeGetChildCount(owner); + + if (childCount == 0) { + // This is an empty set. Nothing to remove. + return; + } + const YGNodeRef firstChild = YGNodeGetChild(owner, 0); + if (firstChild->getOwner() == owner) { + // If the first child has this node as its owner, we assume that it is already unique. + // We can now try to delete a child in this list. + if (owner->removeChild(excludedChild)) { + excludedChild->setLayout( + YGNode().getLayout()); // layout is no longer valid + excludedChild->setOwner(nullptr); + owner->markDirtyAndPropogate(); + } + return; + } + // Otherwise we have to clone the node list except for the child we're trying to delete. + // We don't want to simply clone all children, because then the host will need to free + // the clone of the child that was just deleted. + const YGCloneNodeFunc cloneNodeCallback = + owner->getConfig()->cloneNodeCallback; + uint32_t nextInsertIndex = 0; + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef oldChild = owner->getChild(i); + if (excludedChild == oldChild) { + // Ignore the deleted child. Don't reset its layout or owner since it is still valid + // in the other owner. However, since this owner has now changed, we need to mark it + // as dirty. + owner->markDirtyAndPropogate(); + continue; + } + YGNodeRef newChild = nullptr; + if (cloneNodeCallback) { + newChild = cloneNodeCallback(oldChild, owner, nextInsertIndex); + } + if (newChild == nullptr) { + newChild = YGNodeClone(oldChild); + } + owner->replaceChild(newChild, nextInsertIndex); + newChild->setOwner(owner); + + nextInsertIndex++; + } + while (nextInsertIndex < childCount) { + owner->removeChild(nextInsertIndex); + nextInsertIndex++; + } + } + + void YGNodeRemoveAllChildren(const YGNodeRef owner) { + const uint32_t childCount = YGNodeGetChildCount(owner); + if (childCount == 0) { + // This is an empty set already. Nothing to do. + return; + } + const YGNodeRef firstChild = YGNodeGetChild(owner, 0); + if (firstChild->getOwner() == owner) { + // If the first child has this node as its owner, we assume that this child set is unique. + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef oldChild = YGNodeGetChild(owner, i); + oldChild->setLayout(YGNode().getLayout()); // layout is no longer valid + oldChild->setOwner(nullptr); + } + owner->clearChildren(); + owner->markDirtyAndPropogate(); + return; + } + // Otherwise, we are not the owner of the child set. We don't have to do anything to clear it. + owner->setChildren(YGVector()); + owner->markDirtyAndPropogate(); + } + + static void YGNodeSetChildrenInternal(YGNodeRef const owner, const std::vector &children) + { + if (!owner) { + return; + } + if (children.size() == 0) { + if (YGNodeGetChildCount(owner) > 0) { + for (YGNodeRef const child : owner->getChildren()) { + child->setLayout(YGLayout()); + child->setOwner(nullptr); + } + owner->setChildren(YGVector()); + owner->markDirtyAndPropogate(); + } + } else { + if (YGNodeGetChildCount(owner) > 0) { + for (YGNodeRef const oldChild : owner->getChildren()) { + // Our new children may have nodes in common with the old children. We don't reset these common nodes. + if (std::find(children.begin(), children.end(), oldChild) == children.end()) { + oldChild->setLayout(YGLayout()); + oldChild->setOwner(nullptr); + } + } + } + owner->setChildren(children); + for (YGNodeRef child : children) { + child->setOwner(owner); + } + owner->markDirtyAndPropogate(); + } + } + + void YGNodeSetChildren(YGNodeRef const owner, const YGNodeRef c[], const uint32_t count) { + const YGVector children = {c, c + count}; + YGNodeSetChildrenInternal(owner, children); + } + + void YGNodeSetChildren(YGNodeRef const owner, const std::vector &children) + { + YGNodeSetChildrenInternal(owner, children); + } + + YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) { + if (index < node->getChildren().size()) { + return node->getChild(index); + } + return nullptr; + } + + uint32_t YGNodeGetChildCount(const YGNodeRef node) { + return static_cast(node->getChildren().size()); + } + + YGNodeRef YGNodeGetOwner(const YGNodeRef node) { + return node->getOwner(); + } + + void YGNodeMarkDirty(const YGNodeRef node) { + YGAssertWithNode( + node, + node->getMeasure() != nullptr, + "Only leaf nodes with custom measure functions" + "should manually mark themselves as dirty"); + + node->markDirtyAndPropogate(); + } + + void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) { + if (!(dstNode->getStyle() == srcNode->getStyle())) { + dstNode->setStyle(srcNode->getStyle()); + dstNode->markDirtyAndPropogate(); + } + } + + float YGNodeStyleGetFlexGrow(const YGNodeRef node) { + return node->getStyle().flexGrow.isUndefined() + ? kDefaultFlexGrow + : node->getStyle().flexGrow.getValue(); + } + + float YGNodeStyleGetFlexShrink(const YGNodeRef node) { + return node->getStyle().flexShrink.isUndefined() + ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink + : kDefaultFlexShrink) + : node->getStyle().flexShrink.getValue(); + } + + #define YG_NODE_STYLE_PROPERTY_SETTER_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ + if (node->getStyle().instanceName != paramName) { \ + YGStyle style = node->getStyle(); \ + style.instanceName = paramName; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } + + #define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ + YGValue value = { \ + YGFloatSanitize(paramName), \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \ + }; \ + if ((node->getStyle().instanceName.value != value.value && \ + value.unit != YGUnitUndefined) || \ + node->getStyle().instanceName.unit != value.unit) { \ + YGStyle style = node->getStyle(); \ + style.instanceName = value; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent( \ + const YGNodeRef node, const type paramName) { \ + YGValue value = { \ + YGFloatSanitize(paramName), \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPercent, \ + }; \ + if ((node->getStyle().instanceName.value != value.value && \ + value.unit != YGUnitUndefined) || \ + node->getStyle().instanceName.unit != value.unit) { \ + YGStyle style = node->getStyle(); \ + \ + style.instanceName = value; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } + + #define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ + YGValue value = { \ + YGFloatSanitize(paramName), \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \ + }; \ + if ((node->getStyle().instanceName.value != value.value && \ + value.unit != YGUnitUndefined) || \ + node->getStyle().instanceName.unit != value.unit) { \ + YGStyle style = node->getStyle(); \ + style.instanceName = value; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent( \ + const YGNodeRef node, const type paramName) { \ + if (node->getStyle().instanceName.value != YGFloatSanitize(paramName) || \ + node->getStyle().instanceName.unit != YGUnitPercent) { \ + YGStyle style = node->getStyle(); \ + style.instanceName.value = YGFloatSanitize(paramName); \ + style.instanceName.unit = \ + YGFloatIsUndefined(paramName) ? YGUnitAuto : YGUnitPercent; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Auto(const YGNodeRef node) { \ + if (node->getStyle().instanceName.unit != YGUnitAuto) { \ + YGStyle style = node->getStyle(); \ + style.instanceName.value = 0; \ + style.instanceName.unit = YGUnitAuto; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } + + #define YG_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \ + YG_NODE_STYLE_PROPERTY_SETTER_IMPL(type, name, paramName, instanceName) \ + \ + type YGNodeStyleGet##name(const YGNodeRef node) { \ + return node->getStyle().instanceName; \ + } + + #define YG_NODE_STYLE_PROPERTY_UNIT_IMPL(type, name, paramName, instanceName) \ + YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL( \ + float, name, paramName, instanceName) \ + \ + type YGNodeStyleGet##name(const YGNodeRef node) { \ + YGValue value = node->getStyle().instanceName; \ + if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ + value.value = YGUndefined; \ + } \ + return value; \ + } + + #define YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL( \ + type, name, paramName, instanceName) \ + YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL( \ + float, name, paramName, instanceName) \ + \ + type YGNodeStyleGet##name(const YGNodeRef node) { \ + YGValue value = node->getStyle().instanceName; \ + if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ + value.value = YGUndefined; \ + } \ + return value; \ + } + + #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(type, name, instanceName) \ + void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge) { \ + if (node->getStyle().instanceName[edge].unit != YGUnitAuto) { \ + YGStyle style = node->getStyle(); \ + style.instanceName[edge].value = 0; \ + style.instanceName[edge].unit = YGUnitAuto; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } + + #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name( \ + const YGNodeRef node, const YGEdge edge, const float paramName) { \ + YGValue value = { \ + YGFloatSanitize(paramName), \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \ + }; \ + if ((node->getStyle().instanceName[edge].value != value.value && \ + value.unit != YGUnitUndefined) || \ + node->getStyle().instanceName[edge].unit != value.unit) { \ + YGStyle style = node->getStyle(); \ + style.instanceName[edge] = value; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent( \ + const YGNodeRef node, const YGEdge edge, const float paramName) { \ + YGValue value = { \ + YGFloatSanitize(paramName), \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPercent, \ + }; \ + if ((node->getStyle().instanceName[edge].value != value.value && \ + value.unit != YGUnitUndefined) || \ + node->getStyle().instanceName[edge].unit != value.unit) { \ + YGStyle style = node->getStyle(); \ + style.instanceName[edge] = value; \ + node->setStyle(style); \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + WIN_STRUCT(type) \ + YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \ + YGValue value = node->getStyle().instanceName[edge]; \ + if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ + value.value = YGUndefined; \ + } \ + return WIN_STRUCT_REF(value); \ + } + + #define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ + type YGNodeLayoutGet##name(const YGNodeRef node) { \ + return node->getLayout().instanceName; \ + } + + #define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \ + type YGNodeLayoutGet##name(const YGNodeRef node, const YGEdge edge) { \ + YGAssertWithNode( \ + node, \ + edge <= YGEdgeEnd, \ + "Cannot get layout properties of multi-edge shorthands"); \ + \ + if (edge == YGEdgeLeft) { \ + if (node->getLayout().direction == YGDirectionRTL) { \ + return node->getLayout().instanceName[YGEdgeEnd]; \ + } else { \ + return node->getLayout().instanceName[YGEdgeStart]; \ + } \ + } \ + \ + if (edge == YGEdgeRight) { \ + if (node->getLayout().direction == YGDirectionRTL) { \ + return node->getLayout().instanceName[YGEdgeStart]; \ + } else { \ + return node->getLayout().instanceName[YGEdgeEnd]; \ + } \ + } \ + \ + return node->getLayout().instanceName[edge]; \ + } + + // YG_NODE_PROPERTY_IMPL(void *, Context, context, context); + // YG_NODE_PROPERTY_IMPL(YGPrintFunc, PrintFunc, printFunc, print); + // YG_NODE_PROPERTY_IMPL(bool, HasNewLayout, hasNewLayout, hasNewLayout); + // YG_NODE_PROPERTY_IMPL(YGNodeType, NodeType, nodeType, nodeType); + + YG_NODE_STYLE_PROPERTY_IMPL(YGDirection, Direction, direction, direction); + YG_NODE_STYLE_PROPERTY_IMPL(YGFlexDirection, FlexDirection, flexDirection, flexDirection); + YG_NODE_STYLE_PROPERTY_IMPL(YGJustify, JustifyContent, justifyContent, justifyContent); + YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignContent, alignContent, alignContent); + YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignItems, alignItems, alignItems); + YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignSelf, alignSelf, alignSelf); + YG_NODE_STYLE_PROPERTY_IMPL(YGPositionType, PositionType, positionType, positionType); + YG_NODE_STYLE_PROPERTY_IMPL(YGWrap, FlexWrap, flexWrap, flexWrap); + YG_NODE_STYLE_PROPERTY_IMPL(YGOverflow, Overflow, overflow, overflow); + YG_NODE_STYLE_PROPERTY_IMPL(YGDisplay, Display, display, display); + + // TODO(T26792433): Change the API to accept YGFloatOptional. + void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { + if (node->getStyle().flex != flex) { + YGStyle style = node->getStyle(); + if (YGFloatIsUndefined(flex)) { + style.flex = YGFloatOptional(); + } else { + style.flex = YGFloatOptional(flex); + } + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + // TODO(T26792433): Change the API to accept YGFloatOptional. + float YGNodeStyleGetFlex(const YGNodeRef node) { + return node->getStyle().flex.isUndefined() ? YGUndefined + : node->getStyle().flex.getValue(); + } + + // TODO(T26792433): Change the API to accept YGFloatOptional. + void YGNodeStyleSetFlexGrow(const YGNodeRef node, const float flexGrow) { + if (node->getStyle().flexGrow != flexGrow) { + YGStyle style = node->getStyle(); + if (YGFloatIsUndefined(flexGrow)) { + style.flexGrow = YGFloatOptional(); + } else { + style.flexGrow = YGFloatOptional(flexGrow); + } + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + // TODO(T26792433): Change the API to accept YGFloatOptional. + void YGNodeStyleSetFlexShrink(const YGNodeRef node, const float flexShrink) { + if (node->getStyle().flexShrink != flexShrink) { + YGStyle style = node->getStyle(); + if (YGFloatIsUndefined(flexShrink)) { + style.flexShrink = YGFloatOptional(); + } else { + style.flexShrink = YGFloatOptional(flexShrink); + } + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node) { + YGValue flexBasis = node->getStyle().flexBasis; + if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) { + // TODO(T26792433): Get rid off the use of YGUndefined at client side + flexBasis.value = YGUndefined; + } + return flexBasis; + } + + void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) { + YGValue value = { + YGFloatSanitize(flexBasis), + YGFloatIsUndefined(flexBasis) ? YGUnitUndefined : YGUnitPoint, + }; + if ((node->getStyle().flexBasis.value != value.value && + value.unit != YGUnitUndefined) || + node->getStyle().flexBasis.unit != value.unit) { + YGStyle style = node->getStyle(); + style.flexBasis = value; + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + void YGNodeStyleSetFlexBasisPercent( + const YGNodeRef node, + const float flexBasisPercent) { + if (node->getStyle().flexBasis.value != flexBasisPercent || + node->getStyle().flexBasis.unit != YGUnitPercent) { + YGStyle style = node->getStyle(); + style.flexBasis.value = YGFloatSanitize(flexBasisPercent); + style.flexBasis.unit = + YGFloatIsUndefined(flexBasisPercent) ? YGUnitAuto : YGUnitPercent; + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { + if (node->getStyle().flexBasis.unit != YGUnitAuto) { + YGStyle style = node->getStyle(); + style.flexBasis.value = 0; + style.flexBasis.unit = YGUnitAuto; + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Position, position, position); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Margin, margin, margin); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Margin, margin); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Padding, padding, padding); + + // TODO(T26792433): Change the API to accept YGFloatOptional. + void YGNodeStyleSetBorder( + const YGNodeRef node, + const YGEdge edge, + const float border) { + YGValue value = { + YGFloatSanitize(border), + YGFloatIsUndefined(border) ? YGUnitUndefined : YGUnitPoint, + }; + if ((node->getStyle().border[edge].value != value.value && + value.unit != YGUnitUndefined) || + node->getStyle().border[edge].unit != value.unit) { + YGStyle style = node->getStyle(); + style.border[edge] = value; + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) { + if (node->getStyle().border[edge].unit == YGUnitUndefined || + node->getStyle().border[edge].unit == YGUnitAuto) { + // TODO(T26792433): Rather than returning YGUndefined, change the api to + // return YGFloatOptional. + return YGUndefined; + } + + return node->getStyle().border[edge].value; + } + + // Yoga specific properties, not compatible with flexbox specification + + // TODO(T26792433): Change the API to accept YGFloatOptional. + float YGNodeStyleGetAspectRatio(const YGNodeRef node) { + const YGFloatOptional op = node->getStyle().aspectRatio; + return op.isUndefined() ? YGUndefined : op.getValue(); + } + + // TODO(T26792433): Change the API to accept YGFloatOptional. + void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) { + if (node->getStyle().aspectRatio != aspectRatio) { + YGStyle style = node->getStyle(); + style.aspectRatio = YGFloatOptional(aspectRatio); + node->setStyle(style); + node->markDirtyAndPropogate(); + } + } + + YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Width, width, dimensions[YGDimensionWidth]); + YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Height, height, dimensions[YGDimensionHeight]); + YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinWidth, minWidth, minDimensions[YGDimensionWidth]); + YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinHeight, minHeight, minDimensions[YGDimensionHeight]); + YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MaxWidth, maxWidth, maxDimensions[YGDimensionWidth]); + YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MaxHeight, maxHeight, maxDimensions[YGDimensionHeight]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[YGEdgeLeft]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[YGEdgeTop]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[YGEdgeRight]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Bottom, position[YGEdgeBottom]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[YGDimensionWidth]); + YG_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[YGDimensionHeight]); + YG_NODE_LAYOUT_PROPERTY_IMPL(YGDirection, Direction, direction); + YG_NODE_LAYOUT_PROPERTY_IMPL(bool, HadOverflow, hadOverflow); + + YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Margin, margin); + YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Border, border); + YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding); + + bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) { + return node->getLayout().doesLegacyStretchFlagAffectsLayout; + } + + uint32_t gCurrentGenerationCount = 0; + + bool YGLayoutNodeInternal(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const char *reason, + const YGConfigRef config); + + static void YGNodePrintInternal(const YGNodeRef node, + const YGPrintOptions options) { + std::string str; + facebook::yoga::YGNodeToString(&str, node, options, 0); + YGLog(node, YGLogLevelDebug, str.c_str()); + } + + void YGNodePrint(const YGNodeRef node, const YGPrintOptions options) { + YGNodePrintInternal(node, options); + } + + const std::array leading = { + {YGEdgeTop, YGEdgeBottom, YGEdgeLeft, YGEdgeRight}}; + + const std::array trailing = { + {YGEdgeBottom, YGEdgeTop, YGEdgeRight, YGEdgeLeft}}; + static const std::array pos = {{ + YGEdgeTop, + YGEdgeBottom, + YGEdgeLeft, + YGEdgeRight, + }}; + + static const std::array dim = { + {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; + + static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, + const YGFlexDirection axis, + const float widthSize) { + return YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(axis, widthSize) + + node->getTrailingPaddingAndBorder(axis, widthSize)); + } + + static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) { + const YGAlign align = child->getStyle().alignSelf == YGAlignAuto + ? node->getStyle().alignItems + : child->getStyle().alignSelf; + if (align == YGAlignBaseline && + YGFlexDirectionIsColumn(node->getStyle().flexDirection)) { + return YGAlignFlexStart; + } + return align; + } + + static float YGBaseline(const YGNodeRef node) { + if (node->getBaseline() != nullptr) { + const float baseline = node->getBaseline()( + node, + node->getLayout().measuredDimensions[YGDimensionWidth], + node->getLayout().measuredDimensions[YGDimensionHeight]); + YGAssertWithNode(node, + !YGFloatIsUndefined(baseline), + "Expect custom baseline function to not return NaN"); + return baseline; + } + + YGNodeRef baselineChild = nullptr; + const uint32_t childCount = YGNodeGetChildCount(node); + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + if (child->getLineIndex() > 0) { + break; + } + if (child->getStyle().positionType == YGPositionTypeAbsolute) { + continue; + } + if (YGNodeAlignItem(node, child) == YGAlignBaseline) { + baselineChild = child; + break; + } + + if (baselineChild == nullptr) { + baselineChild = child; + } + } + + if (baselineChild == nullptr) { + return node->getLayout().measuredDimensions[YGDimensionHeight]; + } + + const float baseline = YGBaseline(baselineChild); + return baseline + baselineChild->getLayout().position[YGEdgeTop]; + } + + static bool YGIsBaselineLayout(const YGNodeRef node) { + if (YGFlexDirectionIsColumn(node->getStyle().flexDirection)) { + return false; + } + if (node->getStyle().alignItems == YGAlignBaseline) { + return true; + } + const uint32_t childCount = YGNodeGetChildCount(node); + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + if (child->getStyle().positionType == YGPositionTypeRelative && + child->getStyle().alignSelf == YGAlignBaseline) { + return true; + } + } + + return false; + } + + static inline float YGNodeDimWithMargin(const YGNodeRef node, + const YGFlexDirection axis, + const float widthSize) { + return node->getLayout().measuredDimensions[dim[axis]] + + YGUnwrapFloatOptional( + node->getLeadingMargin(axis, widthSize) + + node->getTrailingMargin(axis, widthSize)); + } + + static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, + const YGFlexDirection axis, + const float ownerSize) { + bool isUndefined = + YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value); + return !( + node->getResolvedDimension(dim[axis]).unit == YGUnitAuto || + node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined || + (node->getResolvedDimension(dim[axis]).unit == YGUnitPoint && + !isUndefined && node->getResolvedDimension(dim[axis]).value < 0.0f) || + (node->getResolvedDimension(dim[axis]).unit == YGUnitPercent && + !isUndefined && + (node->getResolvedDimension(dim[axis]).value < 0.0f || + YGFloatIsUndefined(ownerSize)))); + } + + static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) { + const float value = node->getLayout().measuredDimensions[dim[axis]]; + return !YGFloatIsUndefined(value) && value >= 0.0f; + } + + static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( + const YGNodeRef node, + const YGFlexDirection& axis, + const float& value, + const float& axisSize) { + YGFloatOptional min; + YGFloatOptional max; + + if (YGFlexDirectionIsColumn(axis)) { + min = YGResolveValue( + node->getStyle().minDimensions[YGDimensionHeight], axisSize); + max = YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], axisSize); + } else if (YGFlexDirectionIsRow(axis)) { + min = YGResolveValue( + node->getStyle().minDimensions[YGDimensionWidth], axisSize); + max = YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], axisSize); + } + + if (!max.isUndefined() && max.getValue() >= 0 && value > max.getValue()) { + return max; + } + + if (!min.isUndefined() && min.getValue() >= 0 && value < min.getValue()) { + return min; + } + + return YGFloatOptional(value); + } + + // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't go + // below the + // padding and border amount. + static inline float YGNodeBoundAxis(const YGNodeRef node, + const YGFlexDirection axis, + const float value, + const float axisSize, + const float widthSize) { + return YGFloatMax( + YGUnwrapFloatOptional( + YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)), + YGNodePaddingAndBorderForAxis(node, axis, widthSize)); + } + + static void YGNodeSetChildTrailingPosition(const YGNodeRef node, + const YGNodeRef child, + const YGFlexDirection axis) { + const float size = child->getLayout().measuredDimensions[dim[axis]]; + child->setLayoutPosition( + node->getLayout().measuredDimensions[dim[axis]] - size - + child->getLayout().position[pos[axis]], + trailing[axis]); + } + + static void YGConstrainMaxSizeForMode(const YGNodeRef node, + const enum YGFlexDirection axis, + const float ownerAxisSize, + const float ownerWidth, + YGMeasureMode *mode, + float *size) { + const YGFloatOptional maxSize = + YGResolveValue( + node->getStyle().maxDimensions[dim[axis]], ownerAxisSize) + + YGFloatOptional(node->getMarginForAxis(axis, ownerWidth)); + switch (*mode) { + case YGMeasureModeExactly: + case YGMeasureModeAtMost: + *size = (maxSize.isUndefined() || *size < maxSize.getValue()) + ? *size + : maxSize.getValue(); + break; + case YGMeasureModeUndefined: + if (!maxSize.isUndefined()) { + *mode = YGMeasureModeAtMost; + *size = maxSize.getValue(); + } + break; + } + } + + static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const float ownerWidth, + const float ownerHeight, + const YGMeasureMode heightMode, + const YGDirection direction, + const YGConfigRef config) { + const YGFlexDirection mainAxis = + YGResolveFlexDirection(node->getStyle().flexDirection, direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); + const float mainAxisSize = isMainAxisRow ? width : height; + const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; + + float childWidth; + float childHeight; + YGMeasureMode childWidthMeasureMode; + YGMeasureMode childHeightMeasureMode; + + const YGFloatOptional resolvedFlexBasis = + YGResolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); + const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth); + const bool isColumnStyleDimDefined = + YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, ownerHeight); + + if (!resolvedFlexBasis.isUndefined() && !YGFloatIsUndefined(mainAxisSize)) { + if (child->getLayout().computedFlexBasis.isUndefined() || + (YGConfigIsExperimentalFeatureEnabled( + child->getConfig(), YGExperimentalFeatureWebFlexBasis) && + child->getLayout().computedFlexBasisGeneration != + gCurrentGenerationCount)) { + const YGFloatOptional& paddingAndBorder = YGFloatOptional( + YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); + child->setLayoutComputedFlexBasis( + YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder)); + } + } else if (isMainAxisRow && isRowStyleDimDefined) { + // The width is definite, so use that as the flex basis. + const YGFloatOptional& paddingAndBorder = YGFloatOptional( + YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); + + child->setLayoutComputedFlexBasis(YGFloatOptionalMax( + YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), ownerWidth), + paddingAndBorder)); + } else if (!isMainAxisRow && isColumnStyleDimDefined) { + // The height is definite, so use that as the flex basis. + const YGFloatOptional& paddingAndBorder = + YGFloatOptional(YGNodePaddingAndBorderForAxis( + child, YGFlexDirectionColumn, ownerWidth)); + child->setLayoutComputedFlexBasis(YGFloatOptionalMax( + YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), ownerHeight), + paddingAndBorder)); + } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped + // flex basis). + childWidth = YGUndefined; + childHeight = YGUndefined; + childWidthMeasureMode = YGMeasureModeUndefined; + childHeightMeasureMode = YGMeasureModeUndefined; + + const float& marginRow = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float& marginColumn = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + + if (isRowStyleDimDefined) { + childWidth = + YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), ownerWidth)) + + marginRow; + childWidthMeasureMode = YGMeasureModeExactly; + } + if (isColumnStyleDimDefined) { + childHeight = + YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), ownerHeight)) + + marginColumn; + childHeightMeasureMode = YGMeasureModeExactly; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if ((!isMainAxisRow && node->getStyle().overflow == YGOverflowScroll) || + node->getStyle().overflow != YGOverflowScroll) { + if (YGFloatIsUndefined(childWidth) && !YGFloatIsUndefined(width)) { + childWidth = width; + childWidthMeasureMode = YGMeasureModeAtMost; + } + } + + if ((isMainAxisRow && node->getStyle().overflow == YGOverflowScroll) || + node->getStyle().overflow != YGOverflowScroll) { + if (YGFloatIsUndefined(childHeight) && !YGFloatIsUndefined(height)) { + childHeight = height; + childHeightMeasureMode = YGMeasureModeAtMost; + } + } + + if (!child->getStyle().aspectRatio.isUndefined()) { + if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { + childHeight = marginColumn + + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + childHeightMeasureMode = YGMeasureModeExactly; + } else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { + childWidth = marginRow + + (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); + childWidthMeasureMode = YGMeasureModeExactly; + } + } + + // If child has no defined size in the cross axis and is set to stretch, + // set the cross + // axis to be measured exactly with the available inner width + + const bool hasExactWidth = !YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly; + const bool childWidthStretch = YGNodeAlignItem(node, child) == YGAlignStretch && + childWidthMeasureMode != YGMeasureModeExactly; + if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && childWidthStretch) { + childWidth = width; + childWidthMeasureMode = YGMeasureModeExactly; + if (!child->getStyle().aspectRatio.isUndefined()) { + childHeight = + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + childHeightMeasureMode = YGMeasureModeExactly; + } + } + + const bool hasExactHeight = !YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly; + const bool childHeightStretch = YGNodeAlignItem(node, child) == YGAlignStretch && + childHeightMeasureMode != YGMeasureModeExactly; + if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && childHeightStretch) { + childHeight = height; + childHeightMeasureMode = YGMeasureModeExactly; + + if (!child->getStyle().aspectRatio.isUndefined()) { + childWidth = (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); + childWidthMeasureMode = YGMeasureModeExactly; + } + } + + YGConstrainMaxSizeForMode( + child, YGFlexDirectionRow, ownerWidth, ownerWidth, &childWidthMeasureMode, &childWidth); + YGConstrainMaxSizeForMode(child, + YGFlexDirectionColumn, + ownerHeight, + ownerWidth, + &childHeightMeasureMode, + &childHeight); + + // Measure the child + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + ownerWidth, + ownerHeight, + false, + "measure", + config); + + child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( + child->getLayout().measuredDimensions[dim[mainAxis]], + YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)))); + } + child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); + } + + static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const YGDirection direction, + const YGConfigRef config) { + const YGFlexDirection mainAxis = + YGResolveFlexDirection(node->getStyle().flexDirection, direction); + const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); + + float childWidth = YGUndefined; + float childHeight = YGUndefined; + YGMeasureMode childWidthMeasureMode = YGMeasureModeUndefined; + YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; + + const float& marginRow = + YGUnwrapFloatOptional(child->getMarginForAxis(YGFlexDirectionRow, width)); + const float& marginColumn = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, width)); + + if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { + childWidth = + YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)) + + marginRow; + } else { + // If the child doesn't have a specified width, compute the width based + // on the left/right + // offsets if they're defined. + if (child->isLeadingPositionDefined(YGFlexDirectionRow) && + child->isTrailingPosDefined(YGFlexDirectionRow)) { + childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - + (node->getLeadingBorder(YGFlexDirectionRow) + + node->getTrailingBorder(YGFlexDirectionRow)) - + YGUnwrapFloatOptional( + child->getLeadingPosition(YGFlexDirectionRow, width) + + child->getTrailingPosition(YGFlexDirectionRow, width)); + childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); + } + } + + if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { + childHeight = + YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)) + + marginColumn; + } else { + // If the child doesn't have a specified height, compute the height + // based on the top/bottom + // offsets if they're defined. + if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && + child->isTrailingPosDefined(YGFlexDirectionColumn)) { + childHeight = + node->getLayout().measuredDimensions[YGDimensionHeight] - + (node->getLeadingBorder(YGFlexDirectionColumn) + + node->getTrailingBorder(YGFlexDirectionColumn)) - + YGUnwrapFloatOptional( + child->getLeadingPosition(YGFlexDirectionColumn, height) + + child->getTrailingPosition(YGFlexDirectionColumn, height)); + childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, height, width); + } + } + + // Exactly one dimension needs to be defined for us to be able to do aspect ratio + // calculation. One dimension being the anchor and the other being flexible. + if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { + if (!child->getStyle().aspectRatio.isUndefined()) { + if (YGFloatIsUndefined(childWidth)) { + childWidth = marginRow + + (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); + } else if (YGFloatIsUndefined(childHeight)) { + childHeight = marginColumn + + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + } + } + } + + // If we're still missing one or the other dimension, measure the content. + if (YGFloatIsUndefined(childWidth) || YGFloatIsUndefined(childHeight)) { + childWidthMeasureMode = + YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeExactly; + childHeightMeasureMode = + YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly; + + // If the size of the owner is defined then try to constrain the absolute child to that size + // as well. This allows text within the absolute child to wrap to the size of its owner. + // This is the same behavior as many browsers implement. + if (!isMainAxisRow && YGFloatIsUndefined(childWidth) && + widthMode != YGMeasureModeUndefined && !YGFloatIsUndefined(width) && + width > 0) { + childWidth = width; + childWidthMeasureMode = YGMeasureModeAtMost; + } + + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + childWidth, + childHeight, + false, + "abs-measure", + config); + childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + + YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionRow, width)); + childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + + YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, width)); + } + + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + childWidth, + childHeight, + true, + "abs-layout", + config); + + if (child->isTrailingPosDefined(mainAxis) && + !child->isLeadingPositionDefined(mainAxis)) { + child->setLayoutPosition( + node->getLayout().measuredDimensions[dim[mainAxis]] - + child->getLayout().measuredDimensions[dim[mainAxis]] - + node->getTrailingBorder(mainAxis) - + YGUnwrapFloatOptional(child->getTrailingMargin(mainAxis, width)) - + YGUnwrapFloatOptional(child->getTrailingPosition( + mainAxis, isMainAxisRow ? width : height)), + leading[mainAxis]); + } else if ( + !child->isLeadingPositionDefined(mainAxis) && + node->getStyle().justifyContent == YGJustifyCenter) { + child->setLayoutPosition( + (node->getLayout().measuredDimensions[dim[mainAxis]] - + child->getLayout().measuredDimensions[dim[mainAxis]]) / + 2.0f, + leading[mainAxis]); + } else if ( + !child->isLeadingPositionDefined(mainAxis) && + node->getStyle().justifyContent == YGJustifyFlexEnd) { + child->setLayoutPosition( + (node->getLayout().measuredDimensions[dim[mainAxis]] - + child->getLayout().measuredDimensions[dim[mainAxis]]), + leading[mainAxis]); + } + + if (child->isTrailingPosDefined(crossAxis) && + !child->isLeadingPositionDefined(crossAxis)) { + child->setLayoutPosition( + node->getLayout().measuredDimensions[dim[crossAxis]] - + child->getLayout().measuredDimensions[dim[crossAxis]] - + node->getTrailingBorder(crossAxis) - + YGUnwrapFloatOptional(child->getTrailingMargin(crossAxis, width)) - + YGUnwrapFloatOptional(child->getTrailingPosition( + crossAxis, isMainAxisRow ? height : width)), + leading[crossAxis]); + + } else if ( + !child->isLeadingPositionDefined(crossAxis) && + YGNodeAlignItem(node, child) == YGAlignCenter) { + child->setLayoutPosition( + (node->getLayout().measuredDimensions[dim[crossAxis]] - + child->getLayout().measuredDimensions[dim[crossAxis]]) / + 2.0f, + leading[crossAxis]); + } else if ( + !child->isLeadingPositionDefined(crossAxis) && + ((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^ + (node->getStyle().flexWrap == YGWrapWrapReverse))) { + child->setLayoutPosition( + (node->getLayout().measuredDimensions[dim[crossAxis]] - + child->getLayout().measuredDimensions[dim[crossAxis]]), + leading[crossAxis]); + } + } + + static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { + YGAssertWithNode( + node, + node->getMeasure() != nullptr, + "Expected node to have custom measure function"); + + const float paddingAndBorderAxisRow = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); + const float paddingAndBorderAxisColumn = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, availableWidth); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, availableWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)); + + // We want to make sure we don't call measure with negative size + const float innerWidth = YGFloatIsUndefined(availableWidth) + ? availableWidth + : YGFloatMax(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow); + const float innerHeight = YGFloatIsUndefined(availableHeight) + ? availableHeight + : YGFloatMax( + 0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn); + + if (widthMeasureMode == YGMeasureModeExactly && + heightMeasureMode == YGMeasureModeExactly) { + // Don't bother sizing the text if both dimensions are already defined. + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + YGDimensionWidth); + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + YGDimensionHeight); + } else { + // Measure the text under the current constraints. + const YGSize measuredSize = node->getMeasure()( + node, innerWidth, widthMeasureMode, innerHeight, heightMeasureMode); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + (widthMeasureMode == YGMeasureModeUndefined || + widthMeasureMode == YGMeasureModeAtMost) + ? measuredSize.width + paddingAndBorderAxisRow + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + YGDimensionWidth); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + (heightMeasureMode == YGMeasureModeUndefined || + heightMeasureMode == YGMeasureModeAtMost) + ? measuredSize.height + paddingAndBorderAxisColumn + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + YGDimensionHeight); + } + } + + // For nodes with no children, use the available values if they were provided, + // or the minimum size as indicated by the padding and border sizes. + static void YGNodeEmptyContainerSetMeasuredDimensions(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { + const float paddingAndBorderAxisRow = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); + const float paddingAndBorderAxisColumn = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + (widthMeasureMode == YGMeasureModeUndefined || + widthMeasureMode == YGMeasureModeAtMost) + ? paddingAndBorderAxisRow + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + YGDimensionWidth); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + (heightMeasureMode == YGMeasureModeUndefined || + heightMeasureMode == YGMeasureModeAtMost) + ? paddingAndBorderAxisColumn + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + YGDimensionHeight); + } + + static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight) { + if ((!YGFloatIsUndefined(availableWidth) && + widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) || + (!YGFloatIsUndefined(availableHeight) && + heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || + (widthMeasureMode == YGMeasureModeExactly && + heightMeasureMode == YGMeasureModeExactly)) { + const float& marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float& marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + YGFloatIsUndefined(availableWidth) || + (widthMeasureMode == YGMeasureModeAtMost && + availableWidth < 0.0f) + ? 0.0f + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + YGDimensionWidth); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + YGFloatIsUndefined(availableHeight) || + (heightMeasureMode == YGMeasureModeAtMost && + availableHeight < 0.0f) + ? 0.0f + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + YGDimensionHeight); + return true; + } + + return false; + } + + static void YGZeroOutLayoutRecursivly(const YGNodeRef node) { + memset(&(node->getLayout()), 0, sizeof(YGLayout)); + node->setHasNewLayout(true); + node->cloneChildrenIfNeeded(); + const uint32_t childCount = YGNodeGetChildCount(node); + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = node->getChild(i); + YGZeroOutLayoutRecursivly(child); + } + } + + static float YGNodeCalculateAvailableInnerDim( + const YGNodeRef node, + YGFlexDirection axis, + float availableDim, + float ownerDim) { + YGFlexDirection direction = + YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn; + YGDimension dimension = + YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; + + const float margin = + YGUnwrapFloatOptional(node->getMarginForAxis(direction, ownerDim)); + const float paddingAndBorder = + YGNodePaddingAndBorderForAxis(node, direction, ownerDim); + + float availableInnerDim = availableDim - margin - paddingAndBorder; + // Max dimension overrides predefined dimension value; Min dimension in turn + // overrides both of the above + if (!YGFloatIsUndefined(availableInnerDim)) { + // We want to make sure our available height does not violate min and max + // constraints + const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); + const float minInnerDim = minDimensionOptional.isUndefined() + ? 0.0f + : minDimensionOptional.getValue() - paddingAndBorder; + + const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim) ; + + const float maxInnerDim = maxDimensionOptional.isUndefined() + ? FLT_MAX + : maxDimensionOptional.getValue() - paddingAndBorder; + availableInnerDim = + YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); + } + + return availableInnerDim; + } + + static void YGNodeComputeFlexBasisForChildren( + const YGNodeRef node, + const float availableInnerWidth, + const float availableInnerHeight, + YGMeasureMode widthMeasureMode, + YGMeasureMode heightMeasureMode, + YGDirection direction, + YGFlexDirection mainAxis, + const YGConfigRef config, + bool performLayout, + float& totalOuterFlexBasis) { + YGNodeRef singleFlexChild = nullptr; + YGVector children = node->getChildren(); + YGMeasureMode measureModeMainDim = + YGFlexDirectionIsRow(mainAxis) ? widthMeasureMode : heightMeasureMode; + // If there is only one child with flexGrow + flexShrink it means we can set + // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the + // child to exactly match the remaining space + if (measureModeMainDim == YGMeasureModeExactly) { + for (auto child : children) { + if (singleFlexChild != nullptr) { + if (child->isNodeFlexible()) { + // There is already a flexible child, abort + singleFlexChild = nullptr; + break; + } + } else if ( + child->resolveFlexGrow() > 0.0f && + child->resolveFlexShrink() > 0.0f) { + singleFlexChild = child; + } + } + } + + for (auto child : children) { + child->resolveDimension(); + if (child->getStyle().display == YGDisplayNone) { + YGZeroOutLayoutRecursivly(child); + child->setHasNewLayout(true); + child->setDirty(false); + continue; + } + if (performLayout) { + // Set the initial position (relative to the owner). + const YGDirection childDirection = child->resolveDirection(direction); + const float mainDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerWidth + : availableInnerHeight; + const float crossDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerHeight + : availableInnerWidth; + child->setPosition( + childDirection, mainDim, crossDim, availableInnerWidth); + } + + if (child->getStyle().positionType == YGPositionTypeAbsolute) { + continue; + } + if (child == singleFlexChild) { + child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); + child->setLayoutComputedFlexBasis(YGFloatOptional(0)); + } else { + YGNodeComputeFlexBasisForChild( + node, + child, + availableInnerWidth, + widthMeasureMode, + availableInnerHeight, + availableInnerWidth, + availableInnerHeight, + heightMeasureMode, + direction, + config); + } + + totalOuterFlexBasis += YGUnwrapFloatOptional( + child->getLayout().computedFlexBasis + + child->getMarginForAxis(mainAxis, availableInnerWidth)); + } + } + + // This function assumes that all the children of node have their + // computedFlexBasis properly computed(To do this use + // YGNodeComputeFlexBasisForChildren function). + // This function calculates YGCollectFlexItemsRowMeasurement + static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( + const YGNodeRef& node, + const YGDirection ownerDirection, + const float mainAxisownerSize, + const float availableInnerWidth, + const float availableInnerMainDim, + const uint32_t startOfLineIndex, + const uint32_t lineCount) { + YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {}; + flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); + + float sizeConsumedOnCurrentLineIncludingMinConstraint = 0; + const YGFlexDirection mainAxis = YGResolveFlexDirection( + node->getStyle().flexDirection, node->resolveDirection(ownerDirection)); + const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; + + // Add items to the current line until it's full or we run out of items. + uint32_t endOfLineIndex = startOfLineIndex; + for (; endOfLineIndex < node->getChildrenCount(); endOfLineIndex++) { + const YGNodeRef child = node->getChild(endOfLineIndex); + if (child->getStyle().display == YGDisplayNone || + child->getStyle().positionType == YGPositionTypeAbsolute) { + continue; + } + child->setLineIndex(lineCount); + const float childMarginMainAxis = YGUnwrapFloatOptional( + child->getMarginForAxis(mainAxis, availableInnerWidth)); + const float flexBasisWithMinAndMaxConstraints = + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + child, + mainAxis, + YGUnwrapFloatOptional(child->getLayout().computedFlexBasis), + mainAxisownerSize)); + + // If this is a multi-line flow and this item pushes us over the + // available size, we've + // hit the end of the current line. Break out of the loop and lay out + // the current line. + if (sizeConsumedOnCurrentLineIncludingMinConstraint + + flexBasisWithMinAndMaxConstraints + childMarginMainAxis > + availableInnerMainDim && + isNodeFlexWrap && flexAlgoRowMeasurement.itemsOnLine > 0) { + break; + } + + sizeConsumedOnCurrentLineIncludingMinConstraint += + flexBasisWithMinAndMaxConstraints + childMarginMainAxis; + flexAlgoRowMeasurement.sizeConsumedOnCurrentLine += + flexBasisWithMinAndMaxConstraints + childMarginMainAxis; + flexAlgoRowMeasurement.itemsOnLine++; + + if (child->isNodeFlexible()) { + flexAlgoRowMeasurement.totalFlexGrowFactors += child->resolveFlexGrow(); + + // Unlike the grow factor, the shrink factor is scaled relative to the + // child dimension. + flexAlgoRowMeasurement.totalFlexShrinkScaledFactors += + -child->resolveFlexShrink() * + YGUnwrapFloatOptional(child->getLayout().computedFlexBasis); + } + + flexAlgoRowMeasurement.relativeChildren.push_back(child); + } + + // The total flex factor needs to be floored to 1. + if (flexAlgoRowMeasurement.totalFlexGrowFactors > 0 && + flexAlgoRowMeasurement.totalFlexGrowFactors < 1) { + flexAlgoRowMeasurement.totalFlexGrowFactors = 1; + } + + // The total flex shrink factor needs to be floored to 1. + if (flexAlgoRowMeasurement.totalFlexShrinkScaledFactors > 0 && + flexAlgoRowMeasurement.totalFlexShrinkScaledFactors < 1) { + flexAlgoRowMeasurement.totalFlexShrinkScaledFactors = 1; + } + flexAlgoRowMeasurement.endOfLineIndex = endOfLineIndex; + return flexAlgoRowMeasurement; + } + + // It distributes the free space to the flexible items and ensures that the size + // of the flex items abide the min and max constraints. At the end of this + // function the child nodes would have proper size. Prior using this function + // please ensure that YGDistributeFreeSpaceFirstPass is called. + static float YGDistributeFreeSpaceSecondPass( + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const YGNodeRef node, + const YGFlexDirection mainAxis, + const YGFlexDirection crossAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerCrossDim, + const float availableInnerWidth, + const float availableInnerHeight, + const bool flexBasisOverflows, + const YGMeasureMode measureModeCrossDim, + const bool performLayout, + const YGConfigRef config) { + float childFlexBasis = 0; + float flexShrinkScaledFactor = 0; + float flexGrowFactor = 0; + float deltaFreeSpace = 0; + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); + const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; + + for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { + childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + YGUnwrapFloatOptional( + currentRelativeChild->getLayout().computedFlexBasis), + mainAxisownerSize)); + float updatedMainSize = childFlexBasis; + + if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && + collectedFlexItemsValues.remainingFreeSpace < 0) { + flexShrinkScaledFactor = + -currentRelativeChild->resolveFlexShrink() * childFlexBasis; + // Is this child able to shrink? + if (flexShrinkScaledFactor != 0) { + float childSize; + + if (!YGFloatIsUndefined( + collectedFlexItemsValues.totalFlexShrinkScaledFactors) && + collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) { + childSize = childFlexBasis + flexShrinkScaledFactor; + } else { + childSize = childFlexBasis + + (collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexShrinkScaledFactors) * + flexShrinkScaledFactor; + } + + updatedMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + childSize, + availableInnerMainDim, + availableInnerWidth); + } + } else if ( + !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && + collectedFlexItemsValues.remainingFreeSpace > 0) { + flexGrowFactor = currentRelativeChild->resolveFlexGrow(); + + // Is this child able to grow? + if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) { + updatedMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + childFlexBasis + + collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexGrowFactors * + flexGrowFactor, + availableInnerMainDim, + availableInnerWidth); + } + } + + deltaFreeSpace += updatedMainSize - childFlexBasis; + + const float marginMain = YGUnwrapFloatOptional( + currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)); + const float marginCross = YGUnwrapFloatOptional( + currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)); + + float childCrossSize; + float childMainSize = updatedMainSize + marginMain; + YGMeasureMode childCrossMeasureMode; + YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; + + if (!currentRelativeChild->getStyle().aspectRatio.isUndefined()) { + childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / + currentRelativeChild->getStyle().aspectRatio.getValue() + : (childMainSize - marginMain) * + currentRelativeChild->getStyle().aspectRatio.getValue(); + childCrossMeasureMode = YGMeasureModeExactly; + + childCrossSize += marginCross; + } else if ( + !YGFloatIsUndefined(availableInnerCrossDim) && + !YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim) && + measureModeCrossDim == YGMeasureModeExactly && + !(isNodeFlexWrap && flexBasisOverflows) && + YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch && + currentRelativeChild->marginLeadingValue(crossAxis).unit != + YGUnitAuto && + currentRelativeChild->marginTrailingValue(crossAxis).unit != + YGUnitAuto) { + childCrossSize = availableInnerCrossDim; + childCrossMeasureMode = YGMeasureModeExactly; + } else if (!YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim)) { + childCrossSize = availableInnerCrossDim; + childCrossMeasureMode = YGFloatIsUndefined(childCrossSize) + ? YGMeasureModeUndefined + : YGMeasureModeAtMost; + } else { + childCrossSize = + YGUnwrapFloatOptional(YGResolveValue( + currentRelativeChild->getResolvedDimension(dim[crossAxis]), + availableInnerCrossDim)) + + marginCross; + const bool isLoosePercentageMeasurement = + currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit == + YGUnitPercent && + measureModeCrossDim != YGMeasureModeExactly; + childCrossMeasureMode = + YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement + ? YGMeasureModeUndefined + : YGMeasureModeExactly; + } + + YGConstrainMaxSizeForMode( + currentRelativeChild, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainMeasureMode, + &childMainSize); + YGConstrainMaxSizeForMode( + currentRelativeChild, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossMeasureMode, + &childCrossSize); + + const bool requiresStretchLayout = + !YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim) && + YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch && + currentRelativeChild->marginLeadingValue(crossAxis).unit != + YGUnitAuto && + currentRelativeChild->marginTrailingValue(crossAxis).unit != YGUnitAuto; + + const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; + const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; + + const YGMeasureMode childWidthMeasureMode = + isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; + const YGMeasureMode childHeightMeasureMode = + !isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; + + // Recursively call the layout algorithm for this child with the updated + // main size. + YGLayoutNodeInternal( + currentRelativeChild, + childWidth, + childHeight, + node->getLayout().direction, + childWidthMeasureMode, + childHeightMeasureMode, + availableInnerWidth, + availableInnerHeight, + performLayout && !requiresStretchLayout, + "flex", + config); + node->setLayoutHadOverflow( + node->getLayout().hadOverflow | + currentRelativeChild->getLayout().hadOverflow); + } + return deltaFreeSpace; + } + + // It distributes the free space to the flexible items.For those flexible items + // whose min and max constraints are triggered, those flex item's clamped size + // is removed from the remaingfreespace. + static void YGDistributeFreeSpaceFirstPass( + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const YGFlexDirection mainAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerWidth) { + float flexShrinkScaledFactor = 0; + float flexGrowFactor = 0; + float baseMainSize = 0; + float boundMainSize = 0; + float deltaFreeSpace = 0; + + for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { + float childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + YGUnwrapFloatOptional( + currentRelativeChild->getLayout().computedFlexBasis), + mainAxisownerSize)); + + if (collectedFlexItemsValues.remainingFreeSpace < 0) { + flexShrinkScaledFactor = + -currentRelativeChild->resolveFlexShrink() * childFlexBasis; + + // Is this child able to shrink? + if (!YGFloatIsUndefined(flexShrinkScaledFactor) && + flexShrinkScaledFactor != 0) { + baseMainSize = childFlexBasis + + collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexShrinkScaledFactors * + flexShrinkScaledFactor; + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); + if (!YGFloatIsUndefined(baseMainSize) && + !YGFloatIsUndefined(boundMainSize) && + baseMainSize != boundMainSize) { + // By excluding this item's size and flex factor from remaining, + // this item's + // min/max constraints should also trigger in the second pass + // resulting in the + // item's size calculation being identical in the first and second + // passes. + deltaFreeSpace += boundMainSize - childFlexBasis; + collectedFlexItemsValues.totalFlexShrinkScaledFactors -= + flexShrinkScaledFactor; + } + } + } else if ( + !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && + collectedFlexItemsValues.remainingFreeSpace > 0) { + flexGrowFactor = currentRelativeChild->resolveFlexGrow(); + + // Is this child able to grow? + if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) { + baseMainSize = childFlexBasis + + collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor; + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); + + if (!YGFloatIsUndefined(baseMainSize) && + !YGFloatIsUndefined(boundMainSize) && + baseMainSize != boundMainSize) { + // By excluding this item's size and flex factor from remaining, + // this item's + // min/max constraints should also trigger in the second pass + // resulting in the + // item's size calculation being identical in the first and second + // passes. + deltaFreeSpace += boundMainSize - childFlexBasis; + collectedFlexItemsValues.totalFlexGrowFactors -= flexGrowFactor; + } + } + } + } + collectedFlexItemsValues.remainingFreeSpace -= deltaFreeSpace; + } + + // Do two passes over the flex items to figure out how to distribute the + // remaining space. + // The first pass finds the items whose min/max constraints trigger, + // freezes them at those + // sizes, and excludes those sizes from the remaining space. The second + // pass sets the size + // of each flexible item. It distributes the remaining space amongst the + // items whose min/max + // constraints didn't trigger in pass 1. For the other items, it sets + // their sizes by forcing + // their min/max constraints to trigger again. + // + // This two pass approach for resolving min/max constraints deviates from + // the spec. The + // spec (https://www.w3.org/TR/YG-flexbox-1/#resolve-flexible-lengths) + // describes a process + // that needs to be repeated a variable number of times. The algorithm + // implemented here + // won't handle all cases but it was simpler to implement and it mitigates + // performance + // concerns because we know exactly how many passes it'll do. + // + // At the end of this function the child nodes would have the proper size + // assigned to them. + // + static void YGResolveFlexibleLength( + const YGNodeRef node, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const YGFlexDirection mainAxis, + const YGFlexDirection crossAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerCrossDim, + const float availableInnerWidth, + const float availableInnerHeight, + const bool flexBasisOverflows, + const YGMeasureMode measureModeCrossDim, + const bool performLayout, + const YGConfigRef config) { + const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace; + // First pass: detect the flex items whose min/max constraints trigger + YGDistributeFreeSpaceFirstPass( + collectedFlexItemsValues, + mainAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerWidth); + + // Second pass: resolve the sizes of the flexible items + const float distributedFreeSpace = YGDistributeFreeSpaceSecondPass( + collectedFlexItemsValues, + node, + mainAxis, + crossAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + flexBasisOverflows, + measureModeCrossDim, + performLayout, + config); + + collectedFlexItemsValues.remainingFreeSpace = + originalFreeSpace - distributedFreeSpace; + } + + static void YGJustifyMainAxis( + const YGNodeRef node, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const uint32_t& startOfLineIndex, + const YGFlexDirection& mainAxis, + const YGFlexDirection& crossAxis, + const YGMeasureMode& measureModeMainDim, + const YGMeasureMode& measureModeCrossDim, + const float& mainAxisownerSize, + const float& ownerWidth, + const float& availableInnerMainDim, + const float& availableInnerCrossDim, + const float& availableInnerWidth, + const bool& performLayout) { + const YGStyle style = node->getStyle(); + + // If we are using "at most" rules in the main axis. Calculate the remaining + // space when constraint by the min size defined for the main axis. + if (measureModeMainDim == YGMeasureModeAtMost && + collectedFlexItemsValues.remainingFreeSpace > 0) { + if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined && + !YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize) + .isUndefined()) { + collectedFlexItemsValues.remainingFreeSpace = YGFloatMax( + 0, + YGUnwrapFloatOptional(YGResolveValue( + style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - + (availableInnerMainDim - + collectedFlexItemsValues.remainingFreeSpace)); + } else { + collectedFlexItemsValues.remainingFreeSpace = 0; + } + } + + int numberOfAutoMarginsOnCurrentLine = 0; + for (uint32_t i = startOfLineIndex; + i < collectedFlexItemsValues.endOfLineIndex; + i++) { + const YGNodeRef child = node->getChild(i); + if (child->getStyle().positionType == YGPositionTypeRelative) { + if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { + numberOfAutoMarginsOnCurrentLine++; + } + if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) { + numberOfAutoMarginsOnCurrentLine++; + } + } + } + + // In order to position the elements in the main axis, we have two + // controls. The space between the beginning and the first element + // and the space between each two elements. + float leadingMainDim = 0; + float betweenMainDim = 0; + const YGJustify justifyContent = node->getStyle().justifyContent; + + if (numberOfAutoMarginsOnCurrentLine == 0) { + switch (justifyContent) { + case YGJustifyCenter: + leadingMainDim = collectedFlexItemsValues.remainingFreeSpace / 2; + break; + case YGJustifyFlexEnd: + leadingMainDim = collectedFlexItemsValues.remainingFreeSpace; + break; + case YGJustifySpaceBetween: + if (collectedFlexItemsValues.itemsOnLine > 1) { + betweenMainDim = + YGFloatMax(collectedFlexItemsValues.remainingFreeSpace, 0) / + (collectedFlexItemsValues.itemsOnLine - 1); + } else { + betweenMainDim = 0; + } + break; + case YGJustifySpaceEvenly: + // Space is distributed evenly across all elements + betweenMainDim = collectedFlexItemsValues.remainingFreeSpace / + (collectedFlexItemsValues.itemsOnLine + 1); + leadingMainDim = betweenMainDim; + break; + case YGJustifySpaceAround: + // Space on the edges is half of the space between elements + betweenMainDim = collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.itemsOnLine; + leadingMainDim = betweenMainDim / 2; + break; + case YGJustifyFlexStart: + break; + } + } + + const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); + collectedFlexItemsValues.mainDim = + leadingPaddingAndBorderMain + leadingMainDim; + collectedFlexItemsValues.crossDim = 0; + + for (uint32_t i = startOfLineIndex; + i < collectedFlexItemsValues.endOfLineIndex; + i++) { + const YGNodeRef child = node->getChild(i); + const YGStyle childStyle = child->getStyle(); + const YGLayout childLayout = child->getLayout(); + if (childStyle.display == YGDisplayNone) { + continue; + } + if (childStyle.positionType == YGPositionTypeAbsolute && + child->isLeadingPositionDefined(mainAxis)) { + if (performLayout) { + // In case the child is position absolute and has left/top being + // defined, we override the position to whatever the user said + // (and margin/border). + child->setLayoutPosition( + YGUnwrapFloatOptional( + child->getLeadingPosition(mainAxis, availableInnerMainDim)) + + node->getLeadingBorder(mainAxis) + + YGUnwrapFloatOptional( + child->getLeadingMargin(mainAxis, availableInnerWidth)), + pos[mainAxis]); + } + } else { + // Now that we placed the element, we need to update the variables. + // We need to do that only for relative elements. Absolute elements + // do not take part in that phase. + if (childStyle.positionType == YGPositionTypeRelative) { + if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { + collectedFlexItemsValues.mainDim += + collectedFlexItemsValues.remainingFreeSpace / + numberOfAutoMarginsOnCurrentLine; + } + + if (performLayout) { + child->setLayoutPosition( + childLayout.position[pos[mainAxis]] + + collectedFlexItemsValues.mainDim, + pos[mainAxis]); + } + + if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) { + collectedFlexItemsValues.mainDim += + collectedFlexItemsValues.remainingFreeSpace / + numberOfAutoMarginsOnCurrentLine; + } + bool canSkipFlex = + !performLayout && measureModeCrossDim == YGMeasureModeExactly; + if (canSkipFlex) { + // If we skipped the flex step, then we can't rely on the + // measuredDims because + // they weren't computed. This means we can't call + // YGNodeDimWithMargin. + collectedFlexItemsValues.mainDim += betweenMainDim + + YGUnwrapFloatOptional(child->getMarginForAxis( + mainAxis, availableInnerWidth)) + + YGUnwrapFloatOptional(childLayout.computedFlexBasis); + collectedFlexItemsValues.crossDim = availableInnerCrossDim; + } else { + // The main dimension is the sum of all the elements dimension plus + // the spacing. + collectedFlexItemsValues.mainDim += betweenMainDim + + YGNodeDimWithMargin(child, mainAxis, availableInnerWidth); + + // The cross dimension is the max of the elements dimension since + // there can only be one element in that cross dimension. + collectedFlexItemsValues.crossDim = YGFloatMax( + collectedFlexItemsValues.crossDim, + YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); + } + } else if (performLayout) { + child->setLayoutPosition( + childLayout.position[pos[mainAxis]] + + node->getLeadingBorder(mainAxis) + leadingMainDim, + pos[mainAxis]); + } + } + } + collectedFlexItemsValues.mainDim += YGUnwrapFloatOptional( + node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); + } + + // + // This is the main routine that implements a subset of the flexbox layout + // algorithm + // described in the W3C YG documentation: https://www.w3.org/TR/YG3-flexbox/. + // + // Limitations of this algorithm, compared to the full standard: + // * Display property is always assumed to be 'flex' except for Text nodes, + // which + // are assumed to be 'inline-flex'. + // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes + // are + // stacked in document order. + // * The 'order' property is not supported. The order of flex items is always + // defined + // by document order. + // * The 'visibility' property is always assumed to be 'visible'. Values of + // 'collapse' + // and 'hidden' are not supported. + // * There is no support for forced breaks. + // * It does not support vertical inline directions (top-to-bottom or + // bottom-to-top text). + // + // Deviations from standard: + // * Section 4.5 of the spec indicates that all flex items have a default + // minimum + // main size. For text blocks, for example, this is the width of the widest + // word. + // Calculating the minimum width is expensive, so we forego it and assume a + // default + // minimum main size of 0. + // * Min/Max sizes in the main axis are not honored when resolving flexible + // lengths. + // * The spec indicates that the default value for 'flexDirection' is 'row', + // but + // the algorithm below assumes a default of 'column'. + // + // Input parameters: + // - node: current node to be sized and layed out + // - availableWidth & availableHeight: available size to be used for sizing + // the node + // or YGUndefined if the size is not available; interpretation depends on + // layout + // flags + // - ownerDirection: the inline (text) direction within the owner + // (left-to-right or + // right-to-left) + // - widthMeasureMode: indicates the sizing rules for the width (see below + // for explanation) + // - heightMeasureMode: indicates the sizing rules for the height (see below + // for explanation) + // - performLayout: specifies whether the caller is interested in just the + // dimensions + // of the node or it requires the entire node and its subtree to be layed + // out + // (with final positions) + // + // Details: + // This routine is called recursively to lay out subtrees of flexbox + // elements. It uses the + // information in node.style, which is treated as a read-only input. It is + // responsible for + // setting the layout.direction and layout.measuredDimensions fields for the + // input node as well + // as the layout.position and layout.lineIndex fields for its child nodes. + // The + // layout.measuredDimensions field includes any border or padding for the + // node but does + // not include margins. + // + // The spec describes four different layout modes: "fill available", "max + // content", "min + // content", + // and "fit content". Of these, we don't use "min content" because we don't + // support default + // minimum main sizes (see above for details). Each of our measure modes maps + // to a layout mode + // from the spec (https://www.w3.org/TR/YG3-sizing/#terms): + // - YGMeasureModeUndefined: max content + // - YGMeasureModeExactly: fill available + // - YGMeasureModeAtMost: fit content + // + // When calling YGNodelayoutImpl and YGLayoutNodeInternal, if the caller passes + // an available size of + // undefined then it must also pass a measure mode of YGMeasureModeUndefined + // in that dimension. + // + static void YGNodelayoutImpl(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const YGConfigRef config) { + YGAssertWithNode(node, + YGFloatIsUndefined(availableWidth) ? widthMeasureMode == YGMeasureModeUndefined + : true, + "availableWidth is indefinite so widthMeasureMode must be " + "YGMeasureModeUndefined"); + YGAssertWithNode(node, + YGFloatIsUndefined(availableHeight) ? heightMeasureMode == YGMeasureModeUndefined + : true, + "availableHeight is indefinite so heightMeasureMode must be " + "YGMeasureModeUndefined"); + + // Set the resolved resolution in the node's layout. + const YGDirection direction = node->resolveDirection(ownerDirection); + node->setLayoutDirection(direction); + + const YGFlexDirection flexRowDirection = YGResolveFlexDirection(YGFlexDirectionRow, direction); + const YGFlexDirection flexColumnDirection = + YGResolveFlexDirection(YGFlexDirectionColumn, direction); + + node->setLayoutMargin( + YGUnwrapFloatOptional( + node->getLeadingMargin(flexRowDirection, ownerWidth)), + YGEdgeStart); + node->setLayoutMargin( + YGUnwrapFloatOptional( + node->getTrailingMargin(flexRowDirection, ownerWidth)), + YGEdgeEnd); + node->setLayoutMargin( + YGUnwrapFloatOptional( + node->getLeadingMargin(flexColumnDirection, ownerWidth)), + YGEdgeTop); + node->setLayoutMargin( + YGUnwrapFloatOptional( + node->getTrailingMargin(flexColumnDirection, ownerWidth)), + YGEdgeBottom); + + node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); + node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), YGEdgeEnd); + node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop); + node->setLayoutBorder( + node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); + + node->setLayoutPadding( + YGUnwrapFloatOptional( + node->getLeadingPadding(flexRowDirection, ownerWidth)), + YGEdgeStart); + node->setLayoutPadding( + YGUnwrapFloatOptional( + node->getTrailingPadding(flexRowDirection, ownerWidth)), + YGEdgeEnd); + node->setLayoutPadding( + YGUnwrapFloatOptional( + node->getLeadingPadding(flexColumnDirection, ownerWidth)), + YGEdgeTop); + node->setLayoutPadding( + YGUnwrapFloatOptional( + node->getTrailingPadding(flexColumnDirection, ownerWidth)), + YGEdgeBottom); + + if (node->getMeasure() != nullptr) { + YGNodeWithMeasureFuncSetMeasuredDimensions(node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight); + return; + } + + const uint32_t childCount = YGNodeGetChildCount(node); + if (childCount == 0) { + YGNodeEmptyContainerSetMeasuredDimensions(node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight); + return; + } + + // If we're not being asked to perform a full layout we can skip the algorithm if we already know + // the size + if (!performLayout && YGNodeFixedSizeSetMeasuredDimensions(node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight)) { + return; + } + + // At this point we know we're going to perform work. Ensure that each child has a mutable copy. + node->cloneChildrenIfNeeded(); + // Reset layout flags, as they could have changed. + node->setLayoutHadOverflow(false); + + // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM + const YGFlexDirection mainAxis = + YGResolveFlexDirection(node->getStyle().flexDirection, direction); + const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); + const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; + + const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; + const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; + + const float leadingPaddingAndBorderCross = YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)); + const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); + const float paddingAndBorderAxisCross = + YGNodePaddingAndBorderForAxis(node, crossAxis, ownerWidth); + + YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; + YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; + + const float paddingAndBorderAxisRow = + isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; + const float paddingAndBorderAxisColumn = + isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; + + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + + const float minInnerWidth = + YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - + paddingAndBorderAxisRow; + const float maxInnerWidth = + YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - + paddingAndBorderAxisRow; + const float minInnerHeight = + YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - + paddingAndBorderAxisColumn; + const float maxInnerHeight = + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - + paddingAndBorderAxisColumn; + + const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; + const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; + + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS + + float availableInnerWidth = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionRow, availableWidth, ownerWidth); + float availableInnerHeight = YGNodeCalculateAvailableInnerDim( + node, YGFlexDirectionColumn, availableHeight, ownerHeight); + + float availableInnerMainDim = + isMainAxisRow ? availableInnerWidth : availableInnerHeight; + const float availableInnerCrossDim = + isMainAxisRow ? availableInnerHeight : availableInnerWidth; + + float totalOuterFlexBasis = 0; + + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM + + YGNodeComputeFlexBasisForChildren( + node, + availableInnerWidth, + availableInnerHeight, + widthMeasureMode, + heightMeasureMode, + direction, + mainAxis, + config, + performLayout, + totalOuterFlexBasis); + + const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined + ? false + : totalOuterFlexBasis > availableInnerMainDim; + if (isNodeFlexWrap && flexBasisOverflows && + measureModeMainDim == YGMeasureModeAtMost) { + measureModeMainDim = YGMeasureModeExactly; + } + // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES + + // Indexes of children that represent the first and last items in the line. + uint32_t startOfLineIndex = 0; + uint32_t endOfLineIndex = 0; + + // Number of lines. + uint32_t lineCount = 0; + + // Accumulated cross dimensions of all lines so far. + float totalLineCrossDim = 0; + + // Max main dimension of all the lines. + float maxLineMainDim = 0; + YGCollectFlexItemsRowValues collectedFlexItemsValues; + for (; endOfLineIndex < childCount; + lineCount++, startOfLineIndex = endOfLineIndex) { + collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues( + node, + ownerDirection, + mainAxisownerSize, + availableInnerWidth, + availableInnerMainDim, + startOfLineIndex, + lineCount); + endOfLineIndex = collectedFlexItemsValues.endOfLineIndex; + + // If we don't need to measure the cross axis, we can skip the entire flex + // step. + const bool canSkipFlex = + !performLayout && measureModeCrossDim == YGMeasureModeExactly; + + // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS + // Calculate the remaining available space that needs to be allocated. + // If the main dimension size isn't known, it is computed based on + // the line length, so there's no more space left to distribute. + + bool sizeBasedOnContent = false; + // If we don't measure with exact main dimension we want to ensure we don't violate min and max + if (measureModeMainDim != YGMeasureModeExactly) { + if (!YGFloatIsUndefined(minInnerMainDim) && + collectedFlexItemsValues.sizeConsumedOnCurrentLine < + minInnerMainDim) { + availableInnerMainDim = minInnerMainDim; + } else if ( + !YGFloatIsUndefined(maxInnerMainDim) && + collectedFlexItemsValues.sizeConsumedOnCurrentLine > + maxInnerMainDim) { + availableInnerMainDim = maxInnerMainDim; + } else { + if (!node->getConfig()->useLegacyStretchBehaviour && + ((YGFloatIsUndefined( + collectedFlexItemsValues.totalFlexGrowFactors) && + collectedFlexItemsValues.totalFlexGrowFactors == 0) || + (YGFloatIsUndefined(node->resolveFlexGrow()) && + node->resolveFlexGrow() == 0))) { + // If we don't have any children to flex or we can't flex the node + // itself, space we've used is all space we need. Root node also + // should be shrunk to minimum + availableInnerMainDim = + collectedFlexItemsValues.sizeConsumedOnCurrentLine; + } + + if (node->getConfig()->useLegacyStretchBehaviour) { + node->setLayoutDidUseLegacyFlag(true); + } + sizeBasedOnContent = !node->getConfig()->useLegacyStretchBehaviour; + } + } + + if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) { + collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim - + collectedFlexItemsValues.sizeConsumedOnCurrentLine; + } else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) { + // availableInnerMainDim is indefinite which means the node is being sized based on its + // content. + // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 points for + // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. + collectedFlexItemsValues.remainingFreeSpace = + -collectedFlexItemsValues.sizeConsumedOnCurrentLine; + } + + if (!canSkipFlex) { + YGResolveFlexibleLength( + node, + collectedFlexItemsValues, + mainAxis, + crossAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + flexBasisOverflows, + measureModeCrossDim, + performLayout, + config); + } + + node->setLayoutHadOverflow( + node->getLayout().hadOverflow | + (collectedFlexItemsValues.remainingFreeSpace < 0)); + + // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION + + // At this point, all the children have their dimensions set in the main + // axis. + // Their dimensions are also set in the cross axis with the exception of + // items + // that are aligned "stretch". We need to compute these stretch values and + // set the final positions. + + YGJustifyMainAxis( + node, + collectedFlexItemsValues, + startOfLineIndex, + mainAxis, + crossAxis, + measureModeMainDim, + measureModeCrossDim, + mainAxisownerSize, + ownerWidth, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + performLayout); + + float containerCrossAxis = availableInnerCrossDim; + if (measureModeCrossDim == YGMeasureModeUndefined || + measureModeCrossDim == YGMeasureModeAtMost) { + // Compute the cross axis from the max cross dimension of the children. + containerCrossAxis = + YGNodeBoundAxis( + node, + crossAxis, + collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth) - + paddingAndBorderAxisCross; + } + + // If there's no flex wrap, the cross dimension is defined by the container. + if (!isNodeFlexWrap && measureModeCrossDim == YGMeasureModeExactly) { + collectedFlexItemsValues.crossDim = availableInnerCrossDim; + } + + // Clamp to the min/max size specified on the container. + collectedFlexItemsValues.crossDim = + YGNodeBoundAxis( + node, + crossAxis, + collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth) - + paddingAndBorderAxisCross; + + // STEP 7: CROSS-AXIS ALIGNMENT + // We can skip child alignment if we're just measuring the container. + if (performLayout) { + for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { + const YGNodeRef child = node->getChild(i); + if (child->getStyle().display == YGDisplayNone) { + continue; + } + if (child->getStyle().positionType == YGPositionTypeAbsolute) { + // If the child is absolutely positioned and has a + // top/left/bottom/right set, override + // all the previously computed positions to set it correctly. + const bool isChildLeadingPosDefined = + child->isLeadingPositionDefined(crossAxis); + if (isChildLeadingPosDefined) { + child->setLayoutPosition( + YGUnwrapFloatOptional(child->getLeadingPosition( + crossAxis, availableInnerCrossDim)) + + node->getLeadingBorder(crossAxis) + + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), + pos[crossAxis]); + } + // If leading position is not defined or calculations result in Nan, default to border + margin + if (!isChildLeadingPosDefined || + YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { + child->setLayoutPosition( + node->getLeadingBorder(crossAxis) + + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), + pos[crossAxis]); + } + } else { + float leadingCrossDim = leadingPaddingAndBorderCross; + + // For a relative children, we're either using alignItems (owner) or + // alignSelf (child) in order to determine the position in the cross + // axis + const YGAlign alignItem = YGNodeAlignItem(node, child); + + // If the child uses align stretch, we need to lay it out one more + // time, this time + // forcing the cross-axis size to be the computed cross size for the + // current line. + if (alignItem == YGAlignStretch && + child->marginLeadingValue(crossAxis).unit != YGUnitAuto && + child->marginTrailingValue(crossAxis).unit != YGUnitAuto) { + // If the child defines a definite size for its cross axis, there's + // no need to stretch. + if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + float childMainSize = + child->getLayout().measuredDimensions[dim[mainAxis]]; + float childCrossSize = + !child->getStyle().aspectRatio.isUndefined() + ? ((YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth)) + + (isMainAxisRow ? childMainSize / + child->getStyle().aspectRatio.getValue() + : childMainSize * + child->getStyle().aspectRatio.getValue()))) + : collectedFlexItemsValues.crossDim; + + childMainSize += YGUnwrapFloatOptional( + child->getMarginForAxis(mainAxis, availableInnerWidth)); + + YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; + YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; + YGConstrainMaxSizeForMode(child, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainMeasureMode, + &childMainSize); + YGConstrainMaxSizeForMode(child, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossMeasureMode, + &childCrossSize); + + const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; + const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; + + const YGMeasureMode childWidthMeasureMode = + YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined + : YGMeasureModeExactly; + const YGMeasureMode childHeightMeasureMode = + YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined + : YGMeasureModeExactly; + + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + availableInnerWidth, + availableInnerHeight, + true, + "stretch", + config); + } + } else { + const float remainingCrossDim = containerCrossAxis - + YGNodeDimWithMargin(child, crossAxis, availableInnerWidth); + + if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto && + child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { + leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2); + } else if ( + child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { + // No-Op + } else if ( + child->marginLeadingValue(crossAxis).unit == YGUnitAuto) { + leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim); + } else if (alignItem == YGAlignFlexStart) { + // No-Op + } else if (alignItem == YGAlignCenter) { + leadingCrossDim += remainingCrossDim / 2; + } else { + leadingCrossDim += remainingCrossDim; + } + } + // And we apply the position + child->setLayoutPosition( + child->getLayout().position[pos[crossAxis]] + totalLineCrossDim + + leadingCrossDim, + pos[crossAxis]); + } + } + } + + totalLineCrossDim += collectedFlexItemsValues.crossDim; + maxLineMainDim = + YGFloatMax(maxLineMainDim, collectedFlexItemsValues.mainDim); + } + + // STEP 8: MULTI-LINE CONTENT ALIGNMENT + if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) && + !YGFloatIsUndefined(availableInnerCrossDim)) { + const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; + + float crossDimLead = 0; + float currentLead = leadingPaddingAndBorderCross; + + switch (node->getStyle().alignContent) { + case YGAlignFlexEnd: + currentLead += remainingAlignContentDim; + break; + case YGAlignCenter: + currentLead += remainingAlignContentDim / 2; + break; + case YGAlignStretch: + if (availableInnerCrossDim > totalLineCrossDim) { + crossDimLead = remainingAlignContentDim / lineCount; + } + break; + case YGAlignSpaceAround: + if (availableInnerCrossDim > totalLineCrossDim) { + currentLead += remainingAlignContentDim / (2 * lineCount); + if (lineCount > 1) { + crossDimLead = remainingAlignContentDim / lineCount; + } + } else { + currentLead += remainingAlignContentDim / 2; + } + break; + case YGAlignSpaceBetween: + if (availableInnerCrossDim > totalLineCrossDim && lineCount > 1) { + crossDimLead = remainingAlignContentDim / (lineCount - 1); + } + break; + case YGAlignAuto: + case YGAlignFlexStart: + case YGAlignBaseline: + break; + } + + uint32_t endIndex = 0; + for (uint32_t i = 0; i < lineCount; i++) { + const uint32_t startIndex = endIndex; + uint32_t ii; + + // compute the line's height and find the endIndex + float lineHeight = 0; + float maxAscentForCurrentLine = 0; + float maxDescentForCurrentLine = 0; + for (ii = startIndex; ii < childCount; ii++) { + const YGNodeRef child = node->getChild(ii); + if (child->getStyle().display == YGDisplayNone) { + continue; + } + if (child->getStyle().positionType == YGPositionTypeRelative) { + if (child->getLineIndex() != i) { + break; + } + if (YGNodeIsLayoutDimDefined(child, crossAxis)) { + lineHeight = YGFloatMax( + lineHeight, + child->getLayout().measuredDimensions[dim[crossAxis]] + + YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth))); + } + if (YGNodeAlignItem(node, child) == YGAlignBaseline) { + const float ascent = YGBaseline(child) + + YGUnwrapFloatOptional(child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth)); + const float descent = + child->getLayout().measuredDimensions[YGDimensionHeight] + + YGUnwrapFloatOptional(child->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth)) - + ascent; + maxAscentForCurrentLine = + YGFloatMax(maxAscentForCurrentLine, ascent); + maxDescentForCurrentLine = + YGFloatMax(maxDescentForCurrentLine, descent); + lineHeight = YGFloatMax( + lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine); + } + } + } + endIndex = ii; + lineHeight += crossDimLead; + + if (performLayout) { + for (ii = startIndex; ii < endIndex; ii++) { + const YGNodeRef child = node->getChild(ii); + if (child->getStyle().display == YGDisplayNone) { + continue; + } + if (child->getStyle().positionType == YGPositionTypeRelative) { + switch (YGNodeAlignItem(node, child)) { + case YGAlignFlexStart: { + child->setLayoutPosition( + currentLead + + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), + pos[crossAxis]); + break; + } + case YGAlignFlexEnd: { + child->setLayoutPosition( + currentLead + lineHeight - + YGUnwrapFloatOptional(child->getTrailingMargin( + crossAxis, availableInnerWidth)) - + child->getLayout().measuredDimensions[dim[crossAxis]], + pos[crossAxis]); + break; + } + case YGAlignCenter: { + float childHeight = + child->getLayout().measuredDimensions[dim[crossAxis]]; + + child->setLayoutPosition( + currentLead + (lineHeight - childHeight) / 2, + pos[crossAxis]); + break; + } + case YGAlignStretch: { + child->setLayoutPosition( + currentLead + + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), + pos[crossAxis]); + + // Remeasure child with the line height as it as been only measured with the + // owners height yet. + if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + const float childWidth = isMainAxisRow + ? (child->getLayout() + .measuredDimensions[YGDimensionWidth] + + YGUnwrapFloatOptional(child->getMarginForAxis( + mainAxis, availableInnerWidth))) + : lineHeight; + + const float childHeight = !isMainAxisRow + ? (child->getLayout() + .measuredDimensions[YGDimensionHeight] + + YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth))) + : lineHeight; + + if (!(YGFloatsEqual( + childWidth, + child->getLayout() + .measuredDimensions[YGDimensionWidth]) && + YGFloatsEqual( + childHeight, + child->getLayout() + .measuredDimensions[YGDimensionHeight]))) { + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + availableInnerWidth, + availableInnerHeight, + true, + "multiline-stretch", + config); + } + } + break; + } + case YGAlignBaseline: { + child->setLayoutPosition( + currentLead + maxAscentForCurrentLine - YGBaseline(child) + + YGUnwrapFloatOptional(child->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim)), + YGEdgeTop); + + break; + } + case YGAlignAuto: + case YGAlignSpaceBetween: + case YGAlignSpaceAround: + break; + } + } + } + } + + currentLead += lineHeight; + } + } + + // STEP 9: COMPUTING FINAL DIMENSIONS + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + YGDimensionWidth); + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + YGDimensionHeight); + + // If the user didn't specify a width or height for the node, set the + // dimensions based on the children. + if (measureModeMainDim == YGMeasureModeUndefined || + (node->getStyle().overflow != YGOverflowScroll && + measureModeMainDim == YGMeasureModeAtMost)) { + // Clamp the size to the min/max size, if specified, and make sure it + // doesn't go below the padding and border amount. + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, mainAxis, maxLineMainDim, mainAxisownerSize, ownerWidth), + dim[mainAxis]); + + } else if ( + measureModeMainDim == YGMeasureModeAtMost && + node->getStyle().overflow == YGOverflowScroll) { + node->setLayoutMeasuredDimension( + YGFloatMax( + YGFloatMin( + availableInnerMainDim + paddingAndBorderAxisMain, + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + node, mainAxis, maxLineMainDim, mainAxisownerSize))), + paddingAndBorderAxisMain), + dim[mainAxis]); + } + + if (measureModeCrossDim == YGMeasureModeUndefined || + (node->getStyle().overflow != YGOverflowScroll && + measureModeCrossDim == YGMeasureModeAtMost)) { + // Clamp the size to the min/max size, if specified, and make sure it + // doesn't go below the padding and border amount. + + node->setLayoutMeasuredDimension( + YGNodeBoundAxis( + node, + crossAxis, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth), + dim[crossAxis]); + + } else if ( + measureModeCrossDim == YGMeasureModeAtMost && + node->getStyle().overflow == YGOverflowScroll) { + node->setLayoutMeasuredDimension( + YGFloatMax( + YGFloatMin( + availableInnerCrossDim + paddingAndBorderAxisCross, + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + node, + crossAxis, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisownerSize))), + paddingAndBorderAxisCross), + dim[crossAxis]); + } + + // As we only wrapped in normal direction yet, we need to reverse the positions on wrap-reverse. + if (performLayout && node->getStyle().flexWrap == YGWrapWrapReverse) { + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + if (child->getStyle().positionType == YGPositionTypeRelative) { + child->setLayoutPosition( + node->getLayout().measuredDimensions[dim[crossAxis]] - + child->getLayout().position[pos[crossAxis]] - + child->getLayout().measuredDimensions[dim[crossAxis]], + pos[crossAxis]); + } + } + } + + if (performLayout) { + // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN + for (auto child : node->getChildren()) { + if (child->getStyle().positionType != YGPositionTypeAbsolute) { + continue; + } + YGNodeAbsoluteLayoutChild( + node, + child, + availableInnerWidth, + isMainAxisRow ? measureModeMainDim : measureModeCrossDim, + availableInnerHeight, + direction, + config); + } + + // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN + const bool needsMainTrailingPos = + mainAxis == YGFlexDirectionRowReverse || mainAxis == YGFlexDirectionColumnReverse; + const bool needsCrossTrailingPos = + crossAxis == YGFlexDirectionRowReverse || crossAxis == YGFlexDirectionColumnReverse; + + // Set trailing position if necessary. + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef child = node->getChild(i); + if (child->getStyle().display == YGDisplayNone) { + continue; + } + if (needsMainTrailingPos) { + YGNodeSetChildTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + YGNodeSetChildTrailingPosition(node, child, crossAxis); + } + } + } + } + } + + uint32_t gDepth = 0; + bool gPrintTree = false; + bool gPrintChanges = false; + bool gPrintSkips = false; + + static const char *spacer = " "; + + static const char *YGSpacer(const unsigned long level) { + const size_t spacerLen = strlen(spacer); + if (level > spacerLen) { + return &spacer[0]; + } else { + return &spacer[spacerLen - level]; + } + } + + static const char *YGMeasureModeName(const YGMeasureMode mode, const bool performLayout) { + const char *kMeasureModeNames[YGMeasureModeCount] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; + const char *kLayoutModeNames[YGMeasureModeCount] = {"LAY_UNDEFINED", + "LAY_EXACTLY", + "LAY_AT_" + "MOST"}; + + if (mode >= YGMeasureModeCount) { + return ""; + } + + return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode]; + } + + static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(YGMeasureMode sizeMode, + float size, + float lastComputedSize) { + return sizeMode == YGMeasureModeExactly && YGFloatsEqual(size, lastComputedSize); + } + + static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits(YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, + float lastComputedSize) { + return sizeMode == YGMeasureModeAtMost && lastSizeMode == YGMeasureModeUndefined && + (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); + } + + static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, + float lastSize, + float lastComputedSize) { + return lastSizeMode == YGMeasureModeAtMost && + sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && + !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && + lastSize > size && + (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); + } + + float YGRoundValueToPixelGrid(const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor) { + float scaledValue = value * pointScaleFactor; + float fractial = fmodf(scaledValue, 1.0f); + if (YGFloatsEqual(fractial, 0)) { + // First we check if the value is already rounded + scaledValue = scaledValue - fractial; + } else if (YGFloatsEqual(fractial, 1.0f)) { + scaledValue = scaledValue - fractial + 1.0f; + } else if (forceCeil) { + // Next we check if we need to use forced rounding + scaledValue = scaledValue - fractial + 1.0f; + } else if (forceFloor) { + scaledValue = scaledValue - fractial; + } else { + // Finally we just round the value + scaledValue = scaledValue - fractial + + (!YGFloatIsUndefined(fractial) && + (fractial > 0.5f || YGFloatsEqual(fractial, 0.5f)) + ? 1.0f + : 0.0f); + } + return (YGFloatIsUndefined(scaledValue) || + YGFloatIsUndefined(pointScaleFactor)) + ? YGUndefined + : scaledValue / pointScaleFactor; + } + + bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, + const float width, + const YGMeasureMode heightMode, + const float height, + const YGMeasureMode lastWidthMode, + const float lastWidth, + const YGMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn, + const YGConfigRef config) { + if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) || + (!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) { + return false; + } + bool useRoundedComparison = + config != nullptr && config->pointScaleFactor != 0; + const float effectiveWidth = + useRoundedComparison ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) + : width; + const float effectiveHeight = + useRoundedComparison ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) + : height; + const float effectiveLastWidth = + useRoundedComparison + ? YGRoundValueToPixelGrid(lastWidth, config->pointScaleFactor, false, false) + : lastWidth; + const float effectiveLastHeight = + useRoundedComparison + ? YGRoundValueToPixelGrid(lastHeight, config->pointScaleFactor, false, false) + : lastHeight; + + const bool hasSameWidthSpec = + lastWidthMode == widthMode && YGFloatsEqual(effectiveLastWidth, effectiveWidth); + const bool hasSameHeightSpec = + lastHeightMode == heightMode && YGFloatsEqual(effectiveLastHeight, effectiveHeight); + + const bool widthIsCompatible = + hasSameWidthSpec || YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(widthMode, + width - marginRow, + lastComputedWidth) || + YGMeasureModeOldSizeIsUnspecifiedAndStillFits(widthMode, + width - marginRow, + lastWidthMode, + lastComputedWidth) || + YGMeasureModeNewMeasureSizeIsStricterAndStillValid( + widthMode, width - marginRow, lastWidthMode, lastWidth, lastComputedWidth); + + const bool heightIsCompatible = + hasSameHeightSpec || YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(heightMode, + height - marginColumn, + lastComputedHeight) || + YGMeasureModeOldSizeIsUnspecifiedAndStillFits(heightMode, + height - marginColumn, + lastHeightMode, + lastComputedHeight) || + YGMeasureModeNewMeasureSizeIsStricterAndStillValid( + heightMode, height - marginColumn, lastHeightMode, lastHeight, lastComputedHeight); + + return widthIsCompatible && heightIsCompatible; + } + + // + // This is a wrapper around the YGNodelayoutImpl function. It determines + // whether the layout request is redundant and can be skipped. + // + // Parameters: + // Input parameters are the same as YGNodelayoutImpl (see above) + // Return parameter is true if layout was performed, false if skipped + // + bool YGLayoutNodeInternal(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const char *reason, + const YGConfigRef config) { + YGLayout* layout = &node->getLayout(); + + gDepth++; + + const bool needToVisitNode = + (node->isDirty() && layout->generationCount != gCurrentGenerationCount) || + layout->lastOwnerDirection != ownerDirection; + + if (needToVisitNode) { + // Invalidate the cached results. + layout->nextCachedMeasurementsIndex = 0; + layout->cachedLayout.widthMeasureMode = (YGMeasureMode) -1; + layout->cachedLayout.heightMeasureMode = (YGMeasureMode) -1; + layout->cachedLayout.computedWidth = -1; + layout->cachedLayout.computedHeight = -1; + } + + YGCachedMeasurement* cachedResults = nullptr; + + // Determine whether the results are already cached. We maintain a separate + // cache for layouts and measurements. A layout operation modifies the + // positions + // and dimensions for nodes in the subtree. The algorithm assumes that each + // node + // gets layed out a maximum of one time per tree layout, but multiple + // measurements + // may be required to resolve all of the flex dimensions. + // We handle nodes with measure functions specially here because they are the + // most + // expensive to measure, so it's worth avoiding redundant measurements if at + // all possible. + if (node->getMeasure() != nullptr) { + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + + // First, try to use the layout cache. + if (YGNodeCanUseCachedMeasurement(widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedLayout.widthMeasureMode, + layout->cachedLayout.availableWidth, + layout->cachedLayout.heightMeasureMode, + layout->cachedLayout.availableHeight, + layout->cachedLayout.computedWidth, + layout->cachedLayout.computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { + cachedResults = &layout->cachedLayout; + } else { + // Try to use the measurement cache. + for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (YGNodeCanUseCachedMeasurement(widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedMeasurements[i].widthMeasureMode, + layout->cachedMeasurements[i].availableWidth, + layout->cachedMeasurements[i].heightMeasureMode, + layout->cachedMeasurements[i].availableHeight, + layout->cachedMeasurements[i].computedWidth, + layout->cachedMeasurements[i].computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { + cachedResults = &layout->cachedMeasurements[i]; + break; + } + } + } + } else if (performLayout) { + if (YGFloatsEqual(layout->cachedLayout.availableWidth, availableWidth) && + YGFloatsEqual(layout->cachedLayout.availableHeight, availableHeight) && + layout->cachedLayout.widthMeasureMode == widthMeasureMode && + layout->cachedLayout.heightMeasureMode == heightMeasureMode) { + cachedResults = &layout->cachedLayout; + } + } else { + for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (YGFloatsEqual(layout->cachedMeasurements[i].availableWidth, availableWidth) && + YGFloatsEqual(layout->cachedMeasurements[i].availableHeight, availableHeight) && + layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && + layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { + cachedResults = &layout->cachedMeasurements[i]; + break; + } + } + } + + if (!needToVisitNode && cachedResults != nullptr) { + layout->measuredDimensions[YGDimensionWidth] = cachedResults->computedWidth; + layout->measuredDimensions[YGDimensionHeight] = cachedResults->computedHeight; + + if (gPrintChanges && gPrintSkips) { + YGLog(node, YGLogLevelVerbose, "%s%d.{[skipped] ", YGSpacer(gDepth), gDepth); + if (node->getPrintFunc() != nullptr) { + node->getPrintFunc()(node); + } + YGLog( + node, + YGLogLevelVerbose, + "wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + availableWidth, + availableHeight, + cachedResults->computedWidth, + cachedResults->computedHeight, + reason); + } + } else { + if (gPrintChanges) { + YGLog( + node, + YGLogLevelVerbose, + "%s%d.{%s", + YGSpacer(gDepth), + gDepth, + needToVisitNode ? "*" : ""); + if (node->getPrintFunc() != nullptr) { + node->getPrintFunc()(node); + } + YGLog( + node, + YGLogLevelVerbose, + "wm: %s, hm: %s, aw: %f ah: %f %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + availableWidth, + availableHeight, + reason); + } + + YGNodelayoutImpl(node, + availableWidth, + availableHeight, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + performLayout, + config); + + if (gPrintChanges) { + YGLog( + node, + YGLogLevelVerbose, + "%s%d.}%s", + YGSpacer(gDepth), + gDepth, + needToVisitNode ? "*" : ""); + if (node->getPrintFunc() != nullptr) { + node->getPrintFunc()(node); + } + YGLog( + node, + YGLogLevelVerbose, + "wm: %s, hm: %s, d: (%f, %f) %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + layout->measuredDimensions[YGDimensionWidth], + layout->measuredDimensions[YGDimensionHeight], + reason); + } + + layout->lastOwnerDirection = ownerDirection; + + if (cachedResults == nullptr) { + if (layout->nextCachedMeasurementsIndex == YG_MAX_CACHED_RESULT_COUNT) { + if (gPrintChanges) { + YGLog(node, YGLogLevelVerbose, "Out of cache entries!\n"); + } + layout->nextCachedMeasurementsIndex = 0; + } + + YGCachedMeasurement *newCacheEntry; + if (performLayout) { + // Use the single layout cache entry. + newCacheEntry = &layout->cachedLayout; + } else { + // Allocate a new measurement cache entry. + newCacheEntry = &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex]; + layout->nextCachedMeasurementsIndex++; + } + + newCacheEntry->availableWidth = availableWidth; + newCacheEntry->availableHeight = availableHeight; + newCacheEntry->widthMeasureMode = widthMeasureMode; + newCacheEntry->heightMeasureMode = heightMeasureMode; + newCacheEntry->computedWidth = layout->measuredDimensions[YGDimensionWidth]; + newCacheEntry->computedHeight = layout->measuredDimensions[YGDimensionHeight]; + } + } + + if (performLayout) { + node->setLayoutDimension( + node->getLayout().measuredDimensions[YGDimensionWidth], + YGDimensionWidth); + node->setLayoutDimension( + node->getLayout().measuredDimensions[YGDimensionHeight], + YGDimensionHeight); + + node->setHasNewLayout(true); + node->setDirty(false); + } + + gDepth--; + layout->generationCount = gCurrentGenerationCount; + return (needToVisitNode || cachedResults == nullptr); + } + + void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint) { + YGAssertWithConfig(config, pixelsInPoint >= 0.0f, "Scale factor should not be less than zero"); + + // We store points for Pixel as we will use it for rounding + if (pixelsInPoint == 0.0f) { + // Zero is used to skip rounding + config->pointScaleFactor = 0.0f; + } else { + config->pointScaleFactor = pixelsInPoint; + } + } + + static void YGRoundToPixelGrid(const YGNodeRef node, + const float pointScaleFactor, + const float absoluteLeft, + const float absoluteTop) { + if (pointScaleFactor == 0.0f) { + return; + } + + const float nodeLeft = node->getLayout().position[YGEdgeLeft]; + const float nodeTop = node->getLayout().position[YGEdgeTop]; + + const float nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; + const float nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; + + const float absoluteNodeLeft = absoluteLeft + nodeLeft; + const float absoluteNodeTop = absoluteTop + nodeTop; + + const float absoluteNodeRight = absoluteNodeLeft + nodeWidth; + const float absoluteNodeBottom = absoluteNodeTop + nodeHeight; + + // If a node has a custom measure function we never want to round down its size as this could + // lead to unwanted text truncation. + const bool textRounding = node->getNodeType() == YGNodeTypeText; + + node->setLayoutPosition( + YGRoundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding), + YGEdgeLeft); + + node->setLayoutPosition( + YGRoundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), + YGEdgeTop); + + // We multiply dimension by scale factor and if the result is close to the whole number, we don't + // have any fraction + // To verify if the result is close to whole number we want to check both floor and ceil numbers + const bool hasFractionalWidth = !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) && + !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0); + const bool hasFractionalHeight = !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) && + !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0); + + node->setLayoutDimension( + YGRoundValueToPixelGrid( + absoluteNodeRight, + pointScaleFactor, + (textRounding && hasFractionalWidth), + (textRounding && !hasFractionalWidth)) - + YGRoundValueToPixelGrid( + absoluteNodeLeft, pointScaleFactor, false, textRounding), + YGDimensionWidth); + + node->setLayoutDimension( + YGRoundValueToPixelGrid( + absoluteNodeBottom, + pointScaleFactor, + (textRounding && hasFractionalHeight), + (textRounding && !hasFractionalHeight)) - + YGRoundValueToPixelGrid( + absoluteNodeTop, pointScaleFactor, false, textRounding), + YGDimensionHeight); + + const uint32_t childCount = YGNodeGetChildCount(node); + for (uint32_t i = 0; i < childCount; i++) { + YGRoundToPixelGrid( + YGNodeGetChild(node, i), + pointScaleFactor, + absoluteNodeLeft, + absoluteNodeTop); + } + } + + void YGNodeCalculateLayout( + const YGNodeRef node, + const float ownerWidth, + const float ownerHeight, + const YGDirection ownerDirection) { + // Increment the generation count. This will force the recursive routine to + // visit + // all dirty nodes at least once. Subsequent visits will be skipped if the + // input + // parameters don't change. + gCurrentGenerationCount++; + node->resolveDimension(); + float width = YGUndefined; + YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; + if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { + width = YGUnwrapFloatOptional( + YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + widthMeasureMode = YGMeasureModeExactly; + } else if (!YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) + .isUndefined()) { + width = YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)); + widthMeasureMode = YGMeasureModeAtMost; + } else { + width = ownerWidth; + widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined + : YGMeasureModeExactly; + } + + float height = YGUndefined; + YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; + if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { + height = YGUnwrapFloatOptional( + YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionColumn]), + ownerHeight) + + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + heightMeasureMode = YGMeasureModeExactly; + } else if (!YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], + ownerHeight) + .isUndefined()) { + height = YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); + heightMeasureMode = YGMeasureModeAtMost; + } else { + height = ownerHeight; + heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined + : YGMeasureModeExactly; + } + if (YGLayoutNodeInternal( + node, + width, + height, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + true, + "initial", + node->getConfig())) { + node->setPosition( + node->getLayout().direction, ownerWidth, ownerHeight, ownerWidth); + YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f); + + if (gPrintTree) { + YGNodePrint( + node, + (YGPrintOptions)( + YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); + } + } + + // We want to get rid off `useLegacyStretchBehaviour` from YGConfig. But we + // aren't sure whether client's of yoga have gotten rid off this flag or not. + // So logging this in YGLayout would help to find out the call sites depending + // on this flag. This check would be removed once we are sure no one is + // dependent on this flag anymore. The flag + // `shouldDiffLayoutWithoutLegacyStretchBehaviour` in YGConfig will help to + // run experiments. + if (node->getConfig()->shouldDiffLayoutWithoutLegacyStretchBehaviour && + node->didUseLegacyFlag()) { + const YGNodeRef originalNode = YGNodeDeepClone(node); + originalNode->resolveDimension(); + // Recursively mark nodes as dirty + originalNode->markDirtyAndPropogateDownwards(); + gCurrentGenerationCount++; + // Rerun the layout, and calculate the diff + originalNode->setAndPropogateUseLegacyFlag(false); + if (YGLayoutNodeInternal( + originalNode, + width, + height, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + true, + "initial", + originalNode->getConfig())) { + originalNode->setPosition( + originalNode->getLayout().direction, + ownerWidth, + ownerHeight, + ownerWidth); + YGRoundToPixelGrid( + originalNode, + originalNode->getConfig()->pointScaleFactor, + 0.0f, + 0.0f); + + // Set whether the two layouts are different or not. + node->setLayoutDoesLegacyFlagAffectsLayout( + !originalNode->isLayoutTreeEqualToNode(*node)); + + if (gPrintTree) { + YGNodePrint( + originalNode, + (YGPrintOptions)( + YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); + } + } + YGConfigFreeRecursive(originalNode); + YGNodeFreeRecursive(originalNode); + } + } + + void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { + if (logger != nullptr) { + config->logger = logger; + } else { + #ifdef ANDROID + config->logger = &YGAndroidLog; + #else + config->logger = &YGDefaultLog; + #endif + } + } + + void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( + const YGConfigRef config, + const bool shouldDiffLayout) { + config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout; + } + + static void YGVLog(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args) { + const YGConfigRef logConfig = config != nullptr ? config : YGConfigGetDefault(); + logConfig->logger(logConfig, node, level, format, args); + + if (level == YGLogLevelFatal) { + abort(); + } + } + + void YGLogWithConfig(const YGConfigRef config, YGLogLevel level, const char *format, ...) { + va_list args; + va_start(args, format); + YGVLog(config, nullptr, level, format, args); + va_end(args); + } + + void YGLog(const YGNodeRef node, YGLogLevel level, const char *format, ...) { + va_list args; + va_start(args, format); + YGVLog( + node == nullptr ? nullptr : node->getConfig(), node, level, format, args); + va_end(args); + } + + void YGAssert(const bool condition, const char *message) { + if (!condition) { + YGLog(nullptr, YGLogLevelFatal, "%s\n", message); + } + } + + void YGAssertWithNode(const YGNodeRef node, const bool condition, const char *message) { + if (!condition) { + YGLog(node, YGLogLevelFatal, "%s\n", message); + } + } + + void YGAssertWithConfig(const YGConfigRef config, const bool condition, const char *message) { + if (!condition) { + YGLogWithConfig(config, YGLogLevelFatal, "%s\n", message); + } + } + + void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config, + const YGExperimentalFeature feature, + const bool enabled) { + config->experimentalFeatures[feature] = enabled; + } + + inline bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config, + const YGExperimentalFeature feature) { + return config->experimentalFeatures[feature]; + } + + void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled) { + config->useWebDefaults = enabled; + } + + void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, + const bool useLegacyStretchBehaviour) { + config->useLegacyStretchBehaviour = useLegacyStretchBehaviour; + } + + bool YGConfigGetUseWebDefaults(const YGConfigRef config) { + return config->useWebDefaults; + } + + void YGConfigSetContext(const YGConfigRef config, void *context) { + config->context = context; + } + + void *YGConfigGetContext(const YGConfigRef config) { + return config->context; + } + + void YGConfigSetCloneNodeFunc(const YGConfigRef config, const YGCloneNodeFunc callback) { + config->cloneNodeCallback = callback; + } + + static void YGTraverseChildrenPreOrder(const YGVector& children, const std::function& f) { + for (YGNodeRef node : children) { + f(node); + YGTraverseChildrenPreOrder(node->getChildren(), f); + } + } + + void YGTraversePreOrder(YGNodeRef const node, std::function&& f) { + if (!node) { + return; + } + f(node); + YGTraverseChildrenPreOrder(node->getChildren(), f); + } diff --cc dali-toolkit/third-party/yoga/Yoga.h index 0000000,25eb0eb..0438eff mode 000000,100644..100644 --- a/dali-toolkit/third-party/yoga/Yoga.h +++ b/dali-toolkit/third-party/yoga/Yoga.h @@@ -1,0 -1,327 +1,327 @@@ + /** - * Copyright (c) 2014-present, Facebook, Inc. ++ * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + + #include + #include + #include + #include + #include + #include + + #ifndef __cplusplus + #include + #endif + + /** Large positive number signifies that the property(float) is undefined. + *Earlier we used to have YGundefined as NAN, but the downside of this is that + *we can't use -ffast-math compiler flag as it assumes all floating-point + *calculation involve and result into finite numbers. For more information + *regarding -ffast-math compiler flag in clang, have a look at + *https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math + **/ + #define YGUndefined 10E20F + + #include "YGEnums.h" + #include "YGMacros.h" + + YG_EXTERN_C_BEGIN + + typedef struct YGSize { + float width; + float height; + } YGSize; + + typedef struct YGValue { + float value; + YGUnit unit; + } YGValue; + + extern const YGValue YGValueUndefined; + extern const YGValue YGValueAuto; + + typedef struct YGConfig *YGConfigRef; + + typedef struct YGNode* YGNodeRef; + + typedef YGSize (*YGMeasureFunc)(YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode); + typedef float (*YGBaselineFunc)(YGNodeRef node, const float width, const float height); + typedef void (*YGDirtiedFunc)(YGNodeRef node); + typedef void (*YGPrintFunc)(YGNodeRef node); + typedef int (*YGLogger)(const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char *format, + va_list args); + typedef YGNodeRef ( + *YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex); + + // YGNode + WIN_EXPORT YGNodeRef YGNodeNew(void); + WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config); + WIN_EXPORT YGNodeRef YGNodeClone(const YGNodeRef node); + WIN_EXPORT void YGNodeFree(const YGNodeRef node); + WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node); + WIN_EXPORT void YGNodeReset(const YGNodeRef node); + WIN_EXPORT int32_t YGNodeGetInstanceCount(void); + + WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node, + const YGNodeRef child, + const uint32_t index); + + // This function inserts the child YGNodeRef as a children of the node received + // by parameter and set the Owner of the child object to null. This function is + // expected to be called when using Yoga in persistent mode in order to share a + // YGNodeRef object as a child of two different Yoga trees. The child YGNodeRef + // is expected to be referenced from its original owner and from a clone of its + // original owner. + WIN_EXPORT void YGNodeInsertSharedChild( + const YGNodeRef node, + const YGNodeRef child, + const uint32_t index); + WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child); + WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node); + WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index); + WIN_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node); + WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node); + WIN_EXPORT void YGNodeSetChildren( + YGNodeRef const owner, + const YGNodeRef children[], + const uint32_t count); + + WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection); + + // Mark a node as dirty. Only valid for nodes with a custom measure function + // set. + // YG knows when to mark all other nodes as dirty but because nodes with + // measure functions + // depends on information not known to YG they must perform this dirty + // marking manually. + WIN_EXPORT void YGNodeMarkDirty(const YGNodeRef node); + + // This function marks the current node and all its descendants as dirty. This function is added to test yoga benchmarks. + // This function is not expected to be used in production as calling `YGCalculateLayout` will cause the recalculation of each and every node. + WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(const YGNodeRef node); + + WIN_EXPORT void YGNodePrint(const YGNodeRef node, const YGPrintOptions options); + + WIN_EXPORT bool YGFloatIsUndefined(const float value); + + WIN_EXPORT bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, + const float width, + const YGMeasureMode heightMode, + const float height, + const YGMeasureMode lastWidthMode, + const float lastWidth, + const YGMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn, + const YGConfigRef config); + + WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode); + + #define YG_NODE_PROPERTY(type, name, paramName) \ + WIN_EXPORT void YGNodeSet##name(const YGNodeRef node, type paramName); \ + WIN_EXPORT type YGNodeGet##name(const YGNodeRef node); + + #define YG_NODE_STYLE_PROPERTY(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, const type paramName); \ + WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node); + + #define YG_NODE_STYLE_PROPERTY_UNIT(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, const float paramName); \ + WIN_EXPORT void YGNodeStyleSet##name##Percent(const YGNodeRef node, const float paramName); \ + WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node); + + #define YG_NODE_STYLE_PROPERTY_UNIT_AUTO(type, name, paramName) \ + YG_NODE_STYLE_PROPERTY_UNIT(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node); + + #define YG_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, \ + const YGEdge edge, \ + const type paramName); \ + WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge); + + #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, \ + const YGEdge edge, \ + const float paramName); \ + WIN_EXPORT void YGNodeStyleSet##name##Percent(const YGNodeRef node, \ + const YGEdge edge, \ + const float paramName); \ + WIN_EXPORT WIN_STRUCT(type) YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge); + + #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(type, name) \ + WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge); + + #define YG_NODE_LAYOUT_PROPERTY(type, name) \ + WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node); + + #define YG_NODE_LAYOUT_EDGE_PROPERTY(type, name) \ + WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node, const YGEdge edge); + + void* YGNodeGetContext(YGNodeRef node); + void YGNodeSetContext(YGNodeRef node, void* context); + YGMeasureFunc YGNodeGetMeasureFunc(YGNodeRef node); + void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); + YGBaselineFunc YGNodeGetBaselineFunc(YGNodeRef node); + void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc); + YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node); + void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); + YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node); + void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); + bool YGNodeGetHasNewLayout(YGNodeRef node); + void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); + YGNodeType YGNodeGetNodeType(YGNodeRef node); + void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); + bool YGNodeIsDirty(YGNodeRef node); + bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node); + + YG_NODE_STYLE_PROPERTY(YGDirection, Direction, direction); + YG_NODE_STYLE_PROPERTY(YGFlexDirection, FlexDirection, flexDirection); + YG_NODE_STYLE_PROPERTY(YGJustify, JustifyContent, justifyContent); + YG_NODE_STYLE_PROPERTY(YGAlign, AlignContent, alignContent); + YG_NODE_STYLE_PROPERTY(YGAlign, AlignItems, alignItems); + YG_NODE_STYLE_PROPERTY(YGAlign, AlignSelf, alignSelf); + YG_NODE_STYLE_PROPERTY(YGPositionType, PositionType, positionType); + YG_NODE_STYLE_PROPERTY(YGWrap, FlexWrap, flexWrap); + YG_NODE_STYLE_PROPERTY(YGOverflow, Overflow, overflow); + YG_NODE_STYLE_PROPERTY(YGDisplay, Display, display); + YG_NODE_STYLE_PROPERTY(float, Flex, flex); + YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow); + YG_NODE_STYLE_PROPERTY(float, FlexShrink, flexShrink); + YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, FlexBasis, flexBasis); + + YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Position, position); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Margin, margin); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(YGValue, Margin); + YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Padding, padding); + YG_NODE_STYLE_EDGE_PROPERTY(float, Border, border); + + YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Width, width); + YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Height, height); + YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinWidth, minWidth); + YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinHeight, minHeight); + YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxWidth, maxWidth); + YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxHeight, maxHeight); + + // Yoga specific properties, not compatible with flexbox specification + // Aspect ratio control the size of the undefined dimension of a node. + // Aspect ratio is encoded as a floating point value width/height. e.g. A value of 2 leads to a node + // with a width twice the size of its height while a value of 0.5 gives the opposite effect. + // + // - On a node with a set width/height aspect ratio control the size of the unset dimension + // - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if + // unset + // - On a node with a measure function aspect ratio works as though the measure function measures + // the flex basis + // - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if + // unset + // - Aspect ratio takes min/max dimensions into account + YG_NODE_STYLE_PROPERTY(float, AspectRatio, aspectRatio); + + YG_NODE_LAYOUT_PROPERTY(float, Left); + YG_NODE_LAYOUT_PROPERTY(float, Top); + YG_NODE_LAYOUT_PROPERTY(float, Right); + YG_NODE_LAYOUT_PROPERTY(float, Bottom); + YG_NODE_LAYOUT_PROPERTY(float, Width); + YG_NODE_LAYOUT_PROPERTY(float, Height); + YG_NODE_LAYOUT_PROPERTY(YGDirection, Direction); + YG_NODE_LAYOUT_PROPERTY(bool, HadOverflow); + bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node); + + // Get the computed values for these nodes after performing layout. If they were set using + // point values then the returned value will be the same as YGNodeStyleGetXXX. However if + // they were set using a percentage value then the returned value is the computed value used + // during layout. + YG_NODE_LAYOUT_EDGE_PROPERTY(float, Margin); + YG_NODE_LAYOUT_EDGE_PROPERTY(float, Border); + YG_NODE_LAYOUT_EDGE_PROPERTY(float, Padding); + + WIN_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger); + WIN_EXPORT void YGLog(const YGNodeRef node, YGLogLevel level, const char *message, ...); + WIN_EXPORT void YGLogWithConfig(const YGConfigRef config, YGLogLevel level, const char *format, ...); + WIN_EXPORT void YGAssert(const bool condition, const char *message); + WIN_EXPORT void YGAssertWithNode(const YGNodeRef node, const bool condition, const char *message); + WIN_EXPORT void YGAssertWithConfig(const YGConfigRef config, + const bool condition, + const char *message); + // Set this to number of pixels in 1 point to round calculation results + // If you want to avoid rounding - set PointScaleFactor to 0 + WIN_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint); + void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( + const YGConfigRef config, + const bool shouldDiffLayout); + + // Yoga previously had an error where containers would take the maximum space possible instead of + // the minimum + // like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: + // stretch; + // Because this was such a long-standing bug we must allow legacy users to switch back to this + // behaviour. + WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, + const bool useLegacyStretchBehaviour); + + // YGConfig + WIN_EXPORT YGConfigRef YGConfigNew(void); + WIN_EXPORT void YGConfigFree(const YGConfigRef config); + WIN_EXPORT void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src); + WIN_EXPORT int32_t YGConfigGetInstanceCount(void); + + WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config, + const YGExperimentalFeature feature, + const bool enabled); + WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config, + const YGExperimentalFeature feature); + + // Using the web defaults is the prefered configuration for new projects. + // Usage of non web defaults should be considered as legacy. + WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled); + WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config); + + WIN_EXPORT void YGConfigSetCloneNodeFunc(const YGConfigRef config, + const YGCloneNodeFunc callback); + + // Export only for C# + WIN_EXPORT YGConfigRef YGConfigGetDefault(void); + + WIN_EXPORT void YGConfigSetContext(const YGConfigRef config, void *context); + WIN_EXPORT void *YGConfigGetContext(const YGConfigRef config); + + WIN_EXPORT float YGRoundValueToPixelGrid( + const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor); + + YG_EXTERN_C_END + + #ifdef __cplusplus + + #include + #include + + // Calls f on each node in the tree including the given node argument. + extern void YGTraversePreOrder(YGNodeRef const node, std::function&& f); + + extern void YGNodeSetChildren( + YGNodeRef const owner, + const std::vector& children); + + #endif diff --cc doc/dali-toolkit-doc.h index 982583a,813d2ac..1d38c3e mode 100644,100755..100755 --- a/doc/dali-toolkit-doc.h +++ b/doc/dali-toolkit-doc.h @@@ -2,7 -2,7 +2,7 @@@ #define __DALI_TOOLKIT_DOC_H__ /* -- * Copyright (c) 2016 Samsung Electronics Co., Ltd. ++ * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.